Confundido acerca de PixelFormat

Estoy confundido acerca de PixelFormat en Android.

Mi dispositivo es Motorola Defy.

Tengo dos preguntas:

  • En Android 2.3 getWindowManager().getDefaultDisplay().getPixelFormat() devuelve 4 lo que significa RGB_565 . Por lo que sé mi dispositivo tiene 16M colores, que significa 3 (o 4 con canal alfa) bytes por píxel:
  2^(8*3) = 2^24 = 16M 

Pero el formato RGB_565 tiene 2 bytes (16 bits) por píxel, lo que significa 65K colores:

  2^(8*2) = 2^16 = 65K 

Entonces, ¿por qué getPixelFormat() no devuelve el formato con 3 (o 4 como RGBA) bytes por píxel? ¿Es problemas de controlador de pantalla o algo así? ¿Puedo configurar PixelFormat a RGBA_8888 (o analógico)?

  • En Android 4.1 (ROM personalizada), getPixelFormat() devuelve 5 . Pero este valor es indocumentado. Que significa? En realidad, en esta situación el efecto es el mismo que con la constante 4 . Pero a partir de esta discusión encontré que 5 significa RGBA_8888 (pero no hay prueba para esa declaración). Entonces, ¿cómo puedo averiguar el formato real de la pantalla del dispositivo? También encontré un dispositivo chino en Android 2.2, que también tiene PixelFormat 5 , pero el formato real es 4 (como mi Motorola).

He buscado en Google estas preguntas y no he encontrado nada. Lo único que encontré es que el nexo 7 también tiene formato 5 .

Actualizar:

Encontré el método getWindow().setFormat() pero en realidad no cambia el formato de píxel principal.

Voy a añadir mis dos centavos a esta discusión, aunque debo admitir de antemano que no pude encontrar respuestas concluyentes a todas sus preguntas.

Entonces, ¿por qué getPixelFormat() no devuelve el formato con 3 (o 4 como RGBA) bytes por píxel? ¿Es problemas de controlador de pantalla o algo así? ¿Puedo configurar PixelFormat a RGBA_8888 (o analógico)?

Estoy un poco perplejo acerca de lo que estás preguntando exactamente aquí. El valor devuelto de getPixelFormat() es sólo un entero que proporciona una forma de identificar el formato de píxel activo; No se pretende representar ningún dato compactado en un número (por ejemplo, como con MeasureSpec ). Por desgracia, no tengo una explicación de por qué se devuelve un diferente de lo esperado. Mi mejor conjetura sería que es debido a una decisión de OS, ya que no parece ser una limitación desde un punto de vista de hardware, o, alternativamente, las constantes definidas en la aplicación nativa no coinciden con las de Java. El hecho de que estás recibiendo un 4 como formato de píxel, entonces no necesariamente significa que es realmente RGB_565, si Motorola estropeó las definiciones.

En una nota lateral: En realidad me he encontrado con definiciones constantes desalineadas antes en Android, aunque actualmente no puedo recordar dónde exactamente …

Sólo para confirmar, puede valer la pena imprimir los detalles de formato de píxel en tiempo de ejecución. Si de hecho hay una constante nativa definida que usa un valor de PixelFormat Java pero no coincide, podría revelar el formato "real" de esta manera. Utilice el getPixelFormatInfo(int format, PixelFormat info) , que simplemente delega la recuperación de los valores reales de la implementación nativa.

En Android 4.1 (ROM personalizada), getPixelFormat () devuelve 5. Pero este valor es indocumentado. Que significa?

Como se mencionó anteriormente, a veces las constantes definidas en código nativo no coinciden con las de Java, o no se definen en absoluto. Este es probablemente un caso así. Tendrá que hacer un poco de excavación para averiguar lo que representa, pero es bastante sencillo:

 /** * pixel format definitions */ enum { HAL_PIXEL_FORMAT_RGBA_8888 = 1, HAL_PIXEL_FORMAT_RGBX_8888 = 2, HAL_PIXEL_FORMAT_RGB_888 = 3, HAL_PIXEL_FORMAT_RGB_565 = 4, HAL_PIXEL_FORMAT_BGRA_8888 = 5, HAL_PIXEL_FORMAT_RGBA_5551 = 6, HAL_PIXEL_FORMAT_RGBA_4444 = 7, /* 0x8 - 0xF range unavailable */ HAL_PIXEL_FORMAT_YCbCr_422_SP = 0x10, // NV16 HAL_PIXEL_FORMAT_YCrCb_420_SP = 0x11, // NV21 (_adreno) HAL_PIXEL_FORMAT_YCbCr_422_P = 0x12, // IYUV HAL_PIXEL_FORMAT_YCbCr_420_P = 0x13, // YUV9 HAL_PIXEL_FORMAT_YCbCr_422_I = 0x14, // YUY2 (_adreno) /* 0x15 reserved */ HAL_PIXEL_FORMAT_CbYCrY_422_I = 0x16, // UYVY (_adreno) /* 0x17 reserved */ /* 0x18 - 0x1F range unavailable */ HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED = 0x20, // NV12_adreno_tiled HAL_PIXEL_FORMAT_YCbCr_420_SP = 0x21, // NV12 HAL_PIXEL_FORMAT_YCrCb_420_SP_TILED = 0x22, // NV21_adreno_tiled HAL_PIXEL_FORMAT_YCrCb_422_SP = 0x23, // NV61 HAL_PIXEL_FORMAT_YCrCb_422_P = 0x24, // YV12 (_adreno) }; 

Fuente: hardware.h (líneas 121-148)

Si comparas los valores con los definidos en PixelFormat.java , verás que se suman muy bien (como deberían). También muestra el significado del misterioso 5 , que es BGRA_8888; Una variante de RGBA_8888.

Por cierto, puede intentar determinar los detalles de formato de píxeles para este valor entero utilizando el getPixelFormatInfo(...) antes mencionado pasando en 5 como identificador. Será interesante ver qué se devuelve. Esperaría que muestre valores que coincidan con la definición de BGRA_8888 y, por lo tanto, similares a los dados en la discusión vinculada en la placa de Motorola.

De acuerdo con este hilo en los foros motodev, el valor de retorno 5 corresponde a RGBA_8888. El hilo indica que la documentación para PixelFormat está incompleta y obsoleta, y enlaza con un error que se presentó para ello. Sin embargo, el enlace a ese error ahora devuelve un 404.

Además, no pude encontrar nada en el código fuente de PixelFormat (4.1) que soporta esa afirmación, ya que allí se asigna RGBA_8888 al valor 1.

Mi suposición es que este valor es específico para Motorola y algunos otros dispositivos, ya que estoy viendo la misma salida en mi Nexus 7 y Galaxy Nexus.

EDIT: Envié un correo electrónico a un empleado de Google sobre esto, y me dijo que 5 correspondía a BGRA_8888, como se indica en la respuesta de MH y el hilo del foro de Motorola que he vinculado anteriormente. Él recomendó que archivara un fallo para el problema de la documentación, que he hecho . Por favor, encienda el informe de errores para que la acción se tome más pronto que tarde.

RGBA_8888 corresponde a 1 como se puede ver en el anexo siguiente.

Si va al código relacionado con mPixelFormat encontrará lo siguiente.

 // Following fields are initialized from native code private int mPixelFormat; 

Eso significa que por alguna razón su dispositivo está siendo tratado como RGB_565 debido a una decisión del sistema operativo más que las capacidades de hardware. En realidad, eso me hace sentir curioso.

Curiosamente, las descripciones de Galaxy Nexus y Nexus 7 no parecen tener demasiado en común. GN N7

 public static final int RGBA_8888 = 1; public static final int RGBX_8888 = 2; public static final int RGB_888 = 3; public static final int RGB_565 = 4; @Deprecated public static final int RGBA_5551 = 6; @Deprecated public static final int RGBA_4444 = 7; public static final int A_8 = 8; public static final int L_8 = 9; @Deprecated public static final int LA_88 = 0xA; @Deprecated public static final int RGB_332 = 0xB; 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.