Рисование вращающихся растровых изображений на холсте происходит медленно: есть ли другие варианты? - PullRequest
0 голосов
/ 14 апреля 2011

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

Когда я рисую часы и минуты, я делаю это так (псевдокод):

// without this it looks weird after rotate
Paint smoothPaint = new Paint(FILTER_BITMAP_FLAG);
canvas.drawBitmap(dialBitmap, 0, 0, null);

canvas.rotate(ANGLE_FOR_HOUR_HAND, w/2, h/2);
canvas.drawBitmap(hourBitmap, 0, 0, smoothPaint);

canvas.rotate(ANGLE_FOR_MINUTE_HAND, w/2, h/2);
canvas.drawBitmap(minuteBitmap, 0, 0, smoothPaint);

Это работает нормально, за исключением того, что у меня действительно низкая частота кадров: около 13 кадров в секунду.Если я отключу фильтрацию растровых изображений, она увеличится примерно до 24 кадров в секунду, но все еще будет низкой для меня.

Я знаю, что рисование 2D на Canvas никак не ускоряется, но все же хочу спросить, есть ли другие вариантыдля меня, чтобы ускорить этот код?Рисовать в растровое изображение изначально как-то?Может быть, что-то еще?

Использование OpenGL является опцией, но это не так просто, так как LiveWallpapers не поддерживает рисование GL, поэтому мне нужно использовать сторонние хаки (которые, как я знаю, существуют) для того, чего я бы не хотелделать ...

Ответы [ 3 ]

2 голосов
/ 16 апреля 2011

"Любые другие варианты?" ты спрашиваешь. У вас есть два:

  1. Не используйте растровые изображения. Например, второй образец Cube SDK выдает вращающийся додекаэдр из 20 строк со скоростью 25 кадров в секунду.
  2. Как вы упомянули, иногда вы можете использовать "хак" для графики специального назначения в живых обоях. Я предлагаю вам хотя бы взглянуть на следующие три ... вы можете найти их полезными в один прекрасный день: AndEngine (имеет расширение для живых обоев), LibGDX (позволяет создавать прототипы в среде рабочего стола; живые обои еще находятся в стадии разработки, methinks) и GLWallpaperService (специально разработанный для того, чтобы GLSurfaceView стал живыми обоями).

В своем посте вы говорите, что 24 кадра в секунду "все еще низки" для вас. Насколько я понимаю, 24 кадра в секунду - это примерно предел восприятия человеком (во всяком случае, это то, что использует Flash по умолчанию). Я предлагаю вам не подниматься выше, даже если вы можете, чтобы сохранить срок службы батареи.

Редактировать: Еще один "взлом" для рассмотрения: Renderscript. Вот как работают некоторые из сложных обоев (Galaxy, Grass, Water), которые поставляются со многими телефонами. См. Renderscript, включающий Java-файлы здесь: https://android.googlesource.com/platform/packages/wallpapers/Basic/+/master/src/com/android/wallpaper

1 голос
/ 14 апреля 2011

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

0 голосов
/ 14 апреля 2011

Обнаружив несколько вещей, которые помогли увеличить частоту кадров, опубликую здесь ответ на свой вопрос:)

Сначала нужно использовать Canvas.drawBitmap (Bitmap, Matrix, Paint) перегрузкадля предоставления матрицы вместо использования canvas.save () + canvas.rotate () + canvas.restore () - более эффективно.

Второе: уменьшение размера растровых изображений.Ранее они были дополнены до размера экрана почти hdpi (480 пикселей) с прозрачными пикселями, добавленными вокруг них.После того как я обрезал эти прозрачные пиксели и изменил код рендеринга для учета этого, вращение стало намного более эффективным (как и ожидалось).

...