Android: эффективное обеспечение того, чтобы пиксели в растровом растровом изображении имели только два цвета - PullRequest
0 голосов
/ 08 августа 2011

У меня есть растровое изображение, пиксели которого содержат только два значения argb: чистый черный и чистый прозрачный. Затем я масштабирую растровое изображение в Android, теперь растровое изображение имеет много значений argb: чистый черный и чистый прозрачный и черный с различными уровнями прозрачности (т.е. наполовину прозрачный черный); это связано с автоматической интерполяцией Android. Я хотел бы, чтобы пиксели растровых изображений содержали только два исходных значения argb.

В настоящее время я выполняю это с помощью следующего процесса:

  my_bitmap = Bitmap.createScaledBitmap(BitmapFactory
                    .decodeResource(context.getResources(),
                            R.drawable.my_resource), 
                                  new_width, new height, false);

for (int i = 0; i < my_bitmap.getWidth(); i++) {
                for (int j = 0; j < my_bitmap.getWidth(); j++) {
                    if (my_bitmap.getPixel(i, j) != Color.TRANSPARENT) {
                        my_bitmap.setPixel(i, j, Color.BLACK);
                    }
                }
        }

Это очень медленно на более дешевом телефоне даже для небольшого растрового изображения, кто-нибудь знает, как А) сделать это намного быстрее или Б) масштабировать растровое изображение без появления новых значений argb?

Ответы [ 2 ]

0 голосов
/ 08 августа 2011

Делайте масштабирование в коде, поскольку встроенный алгоритм - это не то, что вам нужно. Вы избежите ненужной интерполяции и вам не придется отменять ее. (Извините за любые ошибки кодирования - я написал это без доступа к IDE или компилятору.)

my_bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.my_resource);
int[] src = new int[my_bitmap.getWidth() * my_bitmap.getHeight()];
my_bitmap.getPixels(src, 0, my_bitmap.getWidth(), 0, 0, my_bitmap.getWidth(), my_bitmap.getHeight());
int[] dst = new int[new_width * new_height];
float scaleX = my_bitmap.getWidth() / new_width;
float scaleY = my_bitmap.getHeight() / new_height;
for (int y = 0; y < new_height; y++) {
    for (int x = 0; x < new_width; x++) {
        int srcY = (int) (y * scaleY);
        int srcX = (int) (x * scaleX);
        dst[y*new_height + x] = src[srcY*my_bitmap.getHeight() + srcX];
    }
}
Bitmap newBitmap = Bitmap.createBitmap(dst, 0, new_width, new_width, new_height, Bitmap.Config.ARGB_8888);
0 голосов
/ 08 августа 2011

Я думаю, что ответ здесь является алгоритмическим.

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

Моя другая идея состояла бы в том, чтобы сгруппировать некоторое количество пикселей вместе и иметь флаг hasChanged или что-то в этом роде и установить его в значение true, когда что-то изменилось, чтобы система знала, что она должна перерисовать эту группу пикселей.Таким образом, вы не перерисовываете вещи чаще, чем необходимо.

Надеюсь, это поможет!

...