Как загрузить 8-битные данные двоичных изображений в текстуру OpenGL ES 2 на Android
Я хочу прочитать данные монохромного изображения с диска в двоичном формате (байт без знака) и отобразить их как текстуру OpenGL ES 2 в Android. В настоящее время я использую Eclipse и эмулятор AVD.
Я могу прочитать данные с диска с помощью InputStream, а затем преобразовать байтовые данные в int, чтобы я мог использовать метод createBitmap.
Я надеялся создать монохромное растровое изображение, используя ALPHA_8 в качестве растрового формата, но если я это сделаю, то при рендеринге текстура будет отображаться в виде сплошного черного цвета. Если я изменю формат растрового изображения на RGB_565, я смогу увидеть части изображения, но, конечно, весь цвет зашифрован, потому что это неправильный формат данных.
Я попытался добавить дополнительные параметры в texImage2D(), чтобы попытаться форсировать формат текстуры и тип данных источника, но Eclipse выдает ошибку, если я использую любой из кодов формата текстуры opengl в аргументах texImage2D.
Я в растерянности, может кто-нибудь сказать мне, как отредактировать это, чтобы получить монохромную текстуру в OpenGL ES?
int w = 640;
int h = 512;
int nP = w * h; //no. of pixels
//load the binary data
byte[] byteArray = new byte[nP];
try {
InputStream fis = mContext.getResources()
.openRawResource(R.raw.testimage); //testimage is a binary file of U8 image data
fis.read(byteArray);
fis.close();
} catch(IOException e) {
// Ignore.
}
System.out.println(byteArray[1]);
//convert byte to int to work with createBitmap (is there a better way to do this?)
int[] intArray = new int[nP];
for (int i=0; i < nP; i++)
{
intArray[i] = byteArray[i];
}
//create bitmap from intArray and send to texture
Bitmap img = Bitmap.createBitmap(intArray, w, h, Bitmap.Config.ALPHA_8);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, img, 0);
img.recycle();
//as the code is the image is black, if I change ALPHA_8 to RGB_565 then I see a corrupted image
Спасибо за вашу помощь,
Люк
2 ответа
После того, как вы загрузили Bitmap
в массив байтов вы также можете использовать glTexImage2D
непосредственно с вашим байтовым массивом. Это было бы что-то в этом роде;
byte data[bitmapLength] = your_byte_data;
ByteBuffer buffer = ByteBuffer.allocateDirect(bitmapLength);
buffer.put(data);
buffer.position(0);
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE,
bitmapWidth, bitmapHeight, 0, GLES20.GL_LUMINANCE,
GLES20.GL_UNSIGNED_BYTE, buffer);
Это должно назначить каждое значение байта в RGB, то же самое значение для каждого, плюс альфа устанавливается в единицу.
Согласно документам createBitmap, этот массив int интерпретируется как массив Color, который имеет вид "(альфа << 24) | (красный << 16) | (зеленый << 8) | синий". Поэтому, когда вы загружаете эти байты и заполняете массив int, вы в настоящее время помещаете данные в синий слот вместо альфа-слота. Таким образом, все ваши альфа-значения равны нулю, что, как я ожидаю, приведет к четкой текстуре. Я верю что ты хочешь
intArray[i] = byteArray[i] << 24;