Проблемы с загрузкой изображений в приложениях J2ME на телефонах Motorola - PullRequest
2 голосов
/ 05 ноября 2008

Стандартный способ загрузки изображения в приложении J2ME - использование метода Image.createImage, рекомендуемый формат изображения - PNG.

Теперь спецификации J2ME не накладывают никаких ограничений на реализацию этого метода или представление Image в памяти, поэтому каждый поставщик имеет свою реализацию.

В частности, Motorola имеет эту действительно дрянную реализацию, в которой PNG полностью декодируется в байтовый массив ARGB во время создания образа. Это означает, что 8K PNG с размерами 176x208 занимает пиковую память около 170 КБ для загрузки, а объем памяти, используемой самим объектом Image, составляет около 145 КБ! На других телефонах, таких как Nokia, Sony Ericsson и т. Д., Для загрузки и сохранения одного и того же изображения требуется около 16 КБ. Я не знаю, какие интеллектуальные оптимизации они используют, но по непонятной причине JVM от Motorola этого не делает.

Это приводит к хаосу в моем приложении J2ME, из-за чего практически невозможно запустить его приличную версию на телефонах Motorola. Я пробовал различные обходные пути, такие как использование байтового массива изображения gzip ARGB и дефлирование во время рисования, но это приводит к замедлению рисования в 10 раз!

Кто-нибудь знает, как обойти эту проблему? Декодер PNG с открытым исходным кодом для J2ME со смартами, которых не хватает Motorola? Или что-то можно сделать с изображением PNG, чтобы уменьшить его объем памяти? (В настоящее время я использовал PNG в индексированном режиме). Любые указатели приветствуются.

Гаури

Ответы [ 6 ]

3 голосов
/ 15 ноября 2008

Одна вещь на Sony Ericsson. Не отдавай им столько уважения. Они также занимают (image_width x image_height x bytes_per_pixel) памяти при загрузке изображений.

Из документа разработчика SE J2ME: " Все изображения хранятся в памяти телефона в 16-битном формате RGB, возможно, с 1-битным или 8-битным альфа-каналом на пиксель. " Итак, как минимум 2 байта. Разница в том, что телефоны Sony Ericsson (я не могу говорить о Nokia) имеют отдельный блок памяти для изображений, который заполняется в первую очередь перед загрузкой изображений в кучу (это можно увидеть, обернув загрузку с помощью Runtime.getRuntime (). FreeMemory () ... размер кучи увеличится всего на пару байтов, что соответствует размеру нового объекта).

Это не защищает Motorola, так как у меня наверняка были проблемы с портированием с телефонов SE на телефоны Motorola, но это не потому, что SE удалось найти способ хранения изображений в куче гораздо более оптимизированным способом. Motorola просто хранит все в куче, и поэтому у вас все быстрее.

Меньшие изображения - хорошая идея, не только во время декодера, но и с точки зрения фрагментации кучи. Это позволит изображениям помещаться в меньшие блоки памяти вместо большого непрерывного блока.

1 голос
/ 06 ноября 2008

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

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

Управление кэшем, вероятно, должно происходить в выделенном потоке.

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

Также помните, что MIDP Canvas обычно не перезагружается. Если вы используете 2 разных вызова Canvas.paint () для рисования 2 разных изображений в 2 разных областях экрана, вы должны иметь возможность отображать оба изображения в течение долгого времени после того, как фактические объекты изображений были собраны так же долго, как и вы. нарисуйте что-нибудь на них.

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

0 голосов
/ 27 апреля 2009

Один из способов уменьшить изображение в формате png - запустить их с помощью программы, подобной png gauntlet уменьшить его размер.

0 голосов
/ 18 ноября 2008

Лучшим решением было бы сохранить ARGB в виде данных (использовать какое-то индексирование для его сжатия) с преимуществами изменения палитры и т. Д. / Без заголовка PNG /. вместо того, чтобы хранить различные изображения PNG и использовать функцию createImage для создания изображения.

0 голосов
/ 10 ноября 2008

Форум разработчиков Motorola предлагает вам вырезать большие изображения до более мелких и загружать эти меньшие полосы вместо всего большого изображения за один раз. Обратите внимание, что это не уменьшает объем памяти изображений в памяти. Для этого все еще требуется сумма (ширина * высота * байт на пиксель) всех полос. Но это уменьшает память, необходимую для декодирования PNG-изображения и загрузки его. Вот что я сейчас делаю. Это помогло некоторым. Но общее использование памяти все еще является проблемой.

0 голосов
/ 05 ноября 2008

PNG имеют тенденцию быть вздутыми.

Почему бы не использовать вместо этого gif.

http://www.ddj.com/mobile/184406435;jsessionid=SBUQN2ECITM5OQSNDLOSKHSCJUNN2JVN?_requestid=76071

...