Android быстрый доступ к пикселям и манипулирование - PullRequest
8 голосов
/ 29 сентября 2011

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

Что касается настольного Java, я использую

int[] pixelsA = ((DataBufferInt) src.getRaster().getDataBuffer()).getData(); 

, которые позволяют мне получить ссылку на пиксельный буфер и обновлять его на лету (минимизировать создание объектов)

В настоящее время это то, что мой эмулятор для Android делает для каждого кадра

@Override
public void onDraw(Canvas canvas)
{
    buffer = Bitmap.createBitmap(pixelsA, 256, 192, Bitmap.Config.RGB_565);
    canvas.drawBitmap(buffer, 0, 0, null);

}   

пикселейA - это массив int [], пиксели А содержат всю информацию о цвете, поэтому каждый кадр должен создавать растровый объект, выполняя

buffer = Bitmap.createBitmap(pixelsA, 256, 192, Bitmap.Config.RGB_565);

, что, на мой взгляд, довольно дорого и медленно.

Есть ли способ эффективно рисовать пиксели с помощью canvas?

Ответы [ 4 ]

10 голосов
/ 29 сентября 2011

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

Создание Bitmap объекта размером с видимый экран.Также создайте объект View и реализуйте метод onDraw.

Затем в нативный код вы загрузите нативную библиотеку libjnigraphics.so, функции поиска AndroidBitmap_lockPixels и AndroidBitmap_unlockPixels.Эти функции определены в источнике Android в bitmap.h.

Затем вы должны вызывать блокировку / разблокировку для битовой карты, получая адрес в необработанных пикселях.Вы должны интерпретировать формат пикселей RGB в соответствии с тем, что он есть на самом деле (16-битный 565 или 32-битный 8888).

После изменения содержимого растрового изображения вы хотите отобразить это на экране.Звоните View.invalidate() на свой View.В его onDraw превратите ваше растровое изображение в заданное Canvas.

Этот метод очень низкого уровня и зависит от фактической реализации Android, однако он очень быстрый, вы можете получить 60fps без проблем.

bitmap.h является частью Android NDK начиная с версии 8 платформы, так что это официальный способ сделать это с Android 2.2.

4 голосов
/ 29 сентября 2011

Вы можете использовать метод drawBitmap , который избегает создания растрового изображения каждый раз, или даже в качестве крайней меры, рисует пиксели по одному с помощью drawPoint .

0 голосов
/ 15 июня 2012

, если пиксели A - это уже массив пикселей (что я и сделал бы из вашего утверждения о содержании цветов), тогда вы можете просто визуализировать их напрямую без преобразования с помощью:

canvas.drawBitmap(pixelsA, 0, 256, 0, 0, 256, 192, false, null);
0 голосов
/ 29 сентября 2011

Не воссоздайте растровое изображение каждый раз. Попробуйте что-то вроде этого:

Bitmap buffer = null;
@Override
public void onDraw(Canvas canvas)
{
    if(buffer == null) buffer = Bitmap.createBitmap(256, 192, Bitmap.Config.RGB_565);
    buffer.copyPixelsFromBuffer(pixelsA);
    canvas.drawBitmap(buffer, 0, 0, null);
}

РЕДАКТИРОВАТЬ: как указано, вам необходимо обновить пиксельный буфер. И растровое изображение должно быть изменчивым, чтобы это произошло.

...