2017-01-14 6 views
1

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

Код У меня есть работы отлично. Но только на эмуляторе или на моем телефоне под управлением Android 6. Все, что ниже этого, и я получаю Out of Memory, прежде чем он завершит инициализацию.

Это, как я загружаю изображения в:

public static Image[] flameIs = new Image[300]; 


for (int i=0;i<300;i++) { 
    if (i>=10) framePref="000"; 
    if (i>=100) framePref="00"; 
    Assets.flameIs[i] = g.newImage("frames/lighter_" + framePref +i+ ".png", ImageFormat.RGB565); 
} 

Так как 300, в формате PNG 8bit, около 12k каждого размера. Мы говорим о изображениях размером менее 4 МБ.

Все приложение впоследствии запускает эти кадры в цикле навсегда.

Есть ли способ избежать этого «из памяти»?

+0

Каков средний размер ваших растровых изображений? – Gauthier

+0

Все они 459x620 – durbnpoisn

+0

Для каждого из ваших изображений требуется 284 580 байт для хранения несжатых данных в памяти (459 x 620 x 8 бит). Для 300 изображений, которые составляют 81 МБ в куче. –

ответ

2

300 Растровые изображения 459x620, загруженные как RGB_565, означают, что вы берете 300 * 459 * 620 * 2 = 171 МБ памяти.

Глядя на https://stackoverflow.com/a/9940415/3413324, которые суммируют размер кучи для популярных устройств, мы можем видеть, что ваши растровые изображения могут превышать лимит даже для последних устройств.

Что вы можете сделать, это:

  • уменьшить размер ваших Bitmaps так, чтобы каждый из них требуется меньше места в памяти

  • Сократите количество Bitmaps вы используете для вашей анимации, тем самым снижая занимаемая память

  • Используйте GIF, который вы можете загрузить с помощью библиотеки. Вы можете иметь то прямое управление размером с уникальным GIF файл

  • Если можно создать анимацию программно
+0

Теперь вы получаете +1. Я попробую это. Мне особенно нравится список кучи памяти, которые вы связали. Я вернусь к этому. – durbnpoisn

+0

Я не знаю, как сделать создание «анимации программно».Это, по сути, одно действие, выполняемое как буфер кадра, то есть постоянное состояние перерисовки. Значит, он просто работает в цикле и освежает весь экран. Вот почему я использую массив для хранения следующего кадра и т. Д. – durbnpoisn

+0

Создание анимации с программным обеспечением может привести к огромному увеличению памяти, когда ваша сцена состоит из нескольких наборов изображений, которые перемещаются. i.e: анимация, требующая перемещения только 10 объектов (битмапов), будет занимать меньше памяти, если вам просто нужно переместить их через код, чем загружать каждый кадр анимации. Хотя это не всегда возможно, всегда хорошо иметь это в виду. – Gauthier

0

Вместо создания 300 кадров анимации, то почему бы не просто преобразовать их в GIF и использовать что-то вроде Скользить, чтобы сделать это? (или даже веб-просмотр, если вы не хотите добавлять новую библиотеку в свой проект)

Это даст вам лучший контроль и переносимость на всех платформах.

С Glide, это будет выглядеть примерно так:

ImageView ImageView = (ImageView) findViewById (R.id.imageView); GlideDrawableImageViewTarget imageViewTarget = новый GlideDrawableImageViewTarget (imageView); Glide.with (this) .load (R.raw.sample_gif) .into (imageViewTarget);

+0

Если эта программа была написана как операция с использованием XML, это будет вариант. Но так, как это написано в настоящее время, он постоянно перерисовывает страницу. Это означает, что GIF не будет сохраняться. Это хорошая идея для следующего раза. – durbnpoisn

Смежные вопросы