Для того чтобы минимизировать использование памяти растровыми картами, но при этом постараться максимально повысить их качество, я хотел бы задать простой вопрос:
Есть ли способ проверить, имеет ли данный файл изображения (.png
файл) прозрачность, используя API, не проверяя каждый пиксель в нем?
Если изображение не имеет прозрачности, то лучше всего использовать другой растровый формат, который использует только значения RGB.
Проблема в том, что Android также не имеет формата только для 3 цветов. Только RGB_565, который, по их словам, ухудшает качество изображения и в котором должна быть включена функция дизеринга.
Есть ли способ считывать только значения RGB и показывать их?
Давайте начнем немного не по теме.
проблема в том, что android также не имеет формата только для 3 цветов. только RGB_565, который, как они говорят, ухудшает качество изображения и который должен иметь включенную функцию дизеринга.
Причина этой проблемы не является специфичной для Android. Речь идет о производительности при рисовании изображений. Наилучшая производительность достигается, если пиксельные данные помещаются точно в 1 32-битную ячейку памяти.
Поэтому наиболее подходящим форматом пикселей является формат ARGB_8888
, который использует ровно 32 бита (24 для цвета, 8 для альфы). При рисовании вам не нужно делать ничего, кроме как перебирать данные изображения, и каждая прочитанная ячейка может быть отрисована напрямую. Единственным недостатком является требуемая память для работы с такими изображениями, как когда они просто находятся в памяти, так и во время их отображения, поскольку графическое оборудование должно передавать больше данных.
Второй лучший вариант - использовать формат, при котором несколько пикселей помещаются в одну ячейку. При использовании 2 пикселей в 32 битах у вас остается 16 бит на пиксель, а одним из форматов, использующих 16 бит, является формат 565. 5бит красный, 6бит зеленый, 5бит синий. При рисовании вы все еще можете работать с ячейками памяти по отдельности, и все, что вам нужно сделать, это разделить 1 ячейку на части. Из-за меньшего объема памяти, необходимого для изображений, рисование иногда может быть даже быстрее, чем при использовании 32-битных цветов. Поскольку в начале развития android память была гораздо большей проблемой, они выбрали этот формат по умолчанию.
И худшая категория форматов - это те, где пиксели не помещаются в ячейки. Если взять только 3 цвета, то получится 24 бита, а их нужно распределить на 2 ячейки в 3 случаях из 4. Например, второй пиксель будет использовать оставшиеся 8 бит из первой ячейки и первые 16 бит из следующей ячейки. Дополнительная работа, необходимая для работы с 24-битными цветами, настолько велика, что она не используется. К тому же при рисовании изображений обычно в какой-то момент все равно появляется альфа, а если нет, то просто используется 32 бит, но альфа-биты игнорируются.
Так что 16-битный подход выглядит уродливо; 24-битный подход не имеет смысла. А поскольку ограничения памяти в Android уже не такие жесткие, как раньше, а аппаратное обеспечение стало быстрее, Android перешел на 32-битный формат по умолчанию (более подробно об этом рассказано на сайте http://www.curious-creature.org/2010/12/08/bitmap-quality-banding-and-dithering/).
Вернемся к вашему реальному вопросу
Есть ли способ проверить, имеет ли данный файл изображения (png файл) прозрачность, используя API, не проверяя каждый пиксель в нем?
Я не знаю. Но изображения JPEG не поддерживают альфа-канал, а изображения PNG обычно имеют альфа-канал. Вы можете просто злоупотребить расширением файла, чтобы получить его в большинстве случаев.
Но я бы посоветовал вам не заморачиваться со всем этим и просто использовать ARGB_8888
и применять хорошие техники загрузки изображений, описанные в документации Android Training о Displaying Bitmaps Efficiently.
Причина, по которой люди сталкиваются с проблемами памяти, обычно заключается либо в том, что в память загружено гораздо больше изображений, чем они отображают в данный момент, либо в том, что они используют гигантские изображения, которые не могут быть отображены на маленьком экране телефона. И, на мой взгляд, разумнее добавить хорошее управление памятью, чем усложнять код для ухудшения качества изображения.
Я'нашел следующие ссылки, которые могут быть полезны для проверки прозрачности png файла. к сожалению, это решение только для png файлов. остальные файлы (такие как webP, bmp, ...) должны иметь другой парсер.
ссылки:
http://www.java2s.com/Code/Java/2D-Graphics-GUI/PNGDecoder.htm
http://hg.l33tlabs.org/twl/file/tip/src/de/matthiasmann/twl/utils/PNGDecoder.java