Подтвердить что ты не робот

Смутно о 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 форматов.

Update:

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

4b9b3361

Ответ 1

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

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

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

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

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

В Android 4.1 (пользовательский ром) 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.

Ответ 2

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

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

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

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

Ответ 3

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;