Смутно о PixelFormat

Я запутался в PixelFormat на Android.

Мое устройство – Motorola Defy.

У меня есть два вопроса:

  • На Android 2.3 getWindowManager().getDefaultDisplay().getPixelFormat() возвращает 4, что означает RGB_565 . Насколько я знаю, у моего устройства 16M цветов, это означает, что 3 (или 4 с альфа-каналом) байтов на пиксель:
  2^(8*3) = 2^24 = 16M 

Но формат RGB_565 имеет 2 байта (16 бит) на пиксель, что означает 65 тыс. Цветов :

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

Итак, почему getPixelFormat() не возвращает формат с 3 (или 4, как RGBA) байтами на пиксель? Это проблемы с драйверами дисплея или что-то еще? Можно ли установить PixelFormat в RGBA_8888 (или аналог)?

  • На Android 4.1 (пользовательский rom) getPixelFormat() возвращает 5 . Но это значение недокументировано. Что это означает? Фактически, в этой ситуации эффект такой же, как с константой 4 . Но из этой дискуссии я обнаружил, что 5 означает RGBA_8888 (но для этого утверждения нет доказательств). Итак, как я могу определить реальный формат экрана устройства? Также я нашел одно китайское устройство на Android 2.2, которое также имеет PixelFormat 5 , но реальный формат – 4 (как моя Motorola).

Я задал эти вопросы и не нашел ничего. Единственное, что я нашел, это то, что у nexus 7 также есть 5 форматов .

Обновить:

Я нашел метод getWindow().setFormat() но на самом деле он не меняет формат основного пикселя.

Solutions Collecting From Web of "Смутно о PixelFormat"

Я просто добавлю свои два цента к этой дискуссии, хотя я должен заранее признать, что не смог найти окончательных ответов на все ваши вопросы.

Итак, почему getPixelFormat() не возвращает формат с 3 (или 4, как RGBA) байтами на пиксель? Это проблемы с драйверами дисплея или что-то еще? Можно ли установить PixelFormat в RGBA_8888 (или аналог)?

Я немного озадачен тем, что вы здесь задаете. Возвращаемое значение getPixelFormat() – это целое число, которое обеспечивает способ идентификации активного формата пикселей; Он не предназначен для представления каких-либо данных, уплотненных в число (например, с помощью MeasureSpec ). К сожалению, у меня нет объяснений, почему другой возвращается, чем вы ожидали. Мое лучшее предположение было бы либо из-за решения ОС, поскольку, похоже, не существует ограничения с точки зрения аппаратного обеспечения, или, альтернативно, константы, определенные в собственной реализации, не соответствуют тем, которые существуют в Java. Тот факт, что вы получаете формат 4 в пикселях, тогда не обязательно означает, что это действительно RGB_565, если Motorola испортила определения.

На стороне примечания: я действительно сталкивался с несогласованными определениями констант раньше в Android, хотя я не могу сейчас вспомнить, где именно …

Просто чтобы подтвердить, может быть стоит распечатать детали формата пикселя во время выполнения. Если действительно существует определенная константа, которая использует значение Java PixelFormat но не совпадает, вы можете, возможно, показать «реальный» формат таким образом. Используйте метод getPixelFormatInfo(int format, PixelFormat info) , который просто делегирует получение фактических значений из собственной реализации.

На Android 4.1 (пользовательский rom) getPixelFormat () возвращает 5. Но это значение недокументировано. Что это означает?

Как упоминалось ранее, иногда константы, определенные в собственном коде, не соответствуют тем, которые существуют в Java, или вообще не определены. Вероятно, это такой случай. Вам нужно будет сделать рытье, чтобы узнать, что он представляет, но это довольно просто:

 /** * 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) }; 

Источник: hardware.h (строки 121-148)

Если бы вы сравнили значения с значениями, определенными в PixelFormat.java , вы обнаружите, что они складываются довольно красиво (как и должно быть). Он также показывает смысл таинственного 5 , который является BGRA_8888; Вариант RGBA_8888.

Кстати, вы можете попытаться определить детали формата пикселя для этого целочисленного значения, используя вышеупомянутый getPixelFormatInfo(...) , передав в качестве идентификатора 5 . Будет интересно посмотреть, что возвращается. Я ожидаю, что он отобразит значения, соответствующие определению BGRA_8888, и, следовательно, аналогично приведенным в связанном обсуждении на плате Motorola.

Согласно этой теме на форумах motodev, возвращаемое значение 5 соответствует RGBA_8888. В потоке указано, что документация для PixelFormat является неполной и устаревшей, и ссылки на ошибку, которая была подана для нее. Однако ссылка на эту ошибку теперь возвращает 404.

Кроме того, я не мог найти ничего в исходном коде PixelFormat (4.1), который поддерживает это требование, так как там RGBA_8888 присваивается значение 1.

Я предполагаю, что это значение специфично для Motorola и некоторых других устройств, поскольку я вижу тот же вывод на своих Nexus 7 и Galaxy Nexus.

EDIT: я отправил по электронной почте сотруднику Google об этом, и он сказал мне, что 5 соответствует BGRA_8888, как указано в ответе MH и в теме форума Motorola, с которой я связан ранее. Он рекомендовал мне написать ошибку для документации, которую я сделал . Пожалуйста, запустите отчет об ошибке, чтобы действие было принято раньше, чем позже.

RGBA_8888 соответствует 1, как показано в приложении ниже.

Если вы перейдете к коду, связанному с mPixelFormat, вы найдете следующее.

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

Это означает, что по какой-то причине ваше устройство рассматривается как RGB_565 из-за решения ОС больше, чем аппаратные возможности. На самом деле, это заставляет меня чувствовать любопытство.

Интересно, что описания Galaxy Nexus и Nexus 7 не так уж много общего. 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;