2012-02-15 3 views
1

По разным причинам я реализую класс, который можно использовать аналогично Bitmap в Android, сохраняя пиксельные данные, когда фактический битмап нужно изменить, прежде чем перейти в OpenGL (Power of 2 размер вещь)Android Bitmap.getPixels неожиданные значения альфа

Я использую ИНТ [] для хранения данных пикселов, поэтому в основном, я мой код, как:

width2 = nearestPowerOf2(width); 
height2 = nearestPowerOf2(height); 
int[] pixels = new int[width2 * height2]; 
bitmap.getPixels(pixels, 0, width2, 0, 0, bitmap.getWidth(), bitmap.getHeight()); 

Теперь, делая шаг назад на мгновение, если я создаю холст и используйте canvas.draw(), чтобы поместить меньшую растровую карту на изображение большего размера, и привязать его в OpenGL, оно отлично рисуется.

Если, однако, я беру данные в пикселях (завернутые в IntBuffer) и привязываю их, значения альфа являются неправильными. Для полноты, так я связываю:

GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, width2, height2, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, pixelsBuffer); 

Я не понимаю, почему это должно произойти.

Я проверил формат растровых изображений, и они все ARGB_8888. И снова, если я рисую растровое изображение напрямую или использую Bitmap.createBitmap(), он работает, но с использованием getPixels нет?

(Причина, по которой я не могу использовать растровое изображение & Canvas, как обычно бывало, заключается в том, что, если я это делаю, у нас заканчиваются нативные на определенных устройствах, которые, по-видимому, очень ленивы в освобождении встроенной памяти Да, я использовал Bitmap.recycle(), я устанавливал битмап в значение null, и я гарантировал, что холст также был установлен в null. Только у нескольких устройств была проблема, но достаточно, чтобы мне нужно было работать.)

This is the image rendered properly via a Bitmap This is the image rendered after using getPixels - please ignore the colors being strange as I understand why this is Here is a side by side, zoomed in for comparison

ответ

1

Почему вы думаете, альфа неверен? Я думаю, что только красные и синие компоненты меняются местами. Это связано с тем, что битмап Android имеет пиксели в порядке RGBA, но OpenGL ES ожидает их в BGRA. Смотрите здесь: http://developer.android.com/reference/android/graphics/Color.html

Компоненты сохраняются следующим образом (альфа < < 24) | (красный < < 16) | (зеленый < < 8) | синий

OpenGL ожидает цвет как (alpha < < 24) | (синий < < 16) | (зеленый < < 8) | красный. Так что просто поменяйте синий и красный компоненты, и с тобой все будет в порядке.

Альтернативным способом было бы использовать расширение GL_EXT_texture_format_BGRA888, чтобы указать формат текстуры как GL_BGRA_EXT.

+0

Во-первых, я хотел бы иметь возможность использовать это расширение, но я не могу найти его в документации или объектной модели Android. Это все Java-код.Затем я добавил пару изображений, чтобы показать проблему. Тот, что слева, является правильным способом, с довольно слабыми пикселями на фоне, вторая проблема. Вы можете видеть, насколько сильнее/ярче/белее пиксели. Это вызывает белый контур игровых объектов, и, может быть, я ошибаюсь, но я чувствую, что он во многом связан с неправильными значениями альфа. –

+0

Чтобы использовать это расширение, вам необходимо передать значение 0x80E1 для форматирования и внутренних параметров аргументов glTexImage2D. Я не уверен, что происходит с двумя вашими нижними изображениями, которые вы разместили. –

1

Пиксели, исходящие из растрового изображения Android, будут ARGB, как вы отметили, затем вы передаете их в glTexImage2D, который ожидает, что пиксели будут в RGBA. Я не уверен, что OpenGL поддерживает ввод типа ARGB, в противном случае вы могли бы сделать что-то вроде:

GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 
        0, 
        GLES20.GL_RGBA, 
        width2, 
        height2, 
        0, 
        GLES20.GL_ARGB,   /** THIS ONE **/ 
        GLES20.GL_UNSIGNED_BYTE, 
        pixelsBuffer); 

В противном случае, вам придется изменить то, что вы получили от Bitmap в RGBA перед подачей его в GL.

+0

Не существует 'GL_ARGB' - http://developer.android.com/reference/android/opengl/GLES20.html. Действительно, вам нужно переставить растровое изображение. Связано: http://stackoverflow.com/questions/7096786/opengl-es-2-0-png-alpha-channel –

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