android bitmap pixel format for glTexImage2D

倖福魔咒の 提交于 2020-01-14 14:49:06

问题


I'm trying to load textures to use with NDK OpenGL from Java with the Bitmap class. It works, but I'm having problems with the pixel format.

First, in Java, I load a bitmap from the assets folder like this:

Bitmap bitmap = BitmapFactory.decodeStream(amgr.open(path));
return bitmap.copy(Bitmap.Config.ARGB_8888, false);

the bitmap config does not have an option for RGBA channel order.

[JNI things happen here]

Using GLES 1, I then buffer the texture like so:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
// `pixels` is the pixel buffer I produced earlier.

As you can see, there is a problem with the pixel format. glTexImage2D does not have an option for ARGB, but the Java Bitmap class does not have an option to create a buffer in RGBA. So I end up with messed up color channels. I do need the alpha channel by the way.

The question is: how do I most efficiently produce a pixel buffer in RGBA8888 format from the Java bitmap class, or, how do I load a GL texture in ARGB8888 format?

Surely there is a way other than manually swapping bytes pixel-by-pixel?

I am currently doing this:

void pxl::swap_channels_ARGB_to_RGBA(void *pixBuf, const int len)
{
    jint *pixels = (jint *)pixBuf;

    for(int i = 0; i < len; i++)
    {
        jint pixel = pixels[i];

        jint a = (pixel >> 24) & 0xFF;
        jint r = (pixel >> 16) & 0xFF;
        jint g = (pixel >>  8) & 0xFF;
        jint b = (pixel >>  0) & 0xFF;

        pixels[i] = (jint)(a | (r << 24 ) | (g << 16) | (b << 8));
    }
}

Or maybe there is another error? Not exactly sure about the glTexImage2D options to be honest.

Thanks!


回答1:


I think there's no method to do that, but you can optimize your algorithm with this

void pxl::swap_channels_ARGB_to_RGBA(void *pixBuf, const int len) {
    jint *pixels = (jint *)pixBuf;

    for(int i = 0; i < len; i++) {
        unsigned int aux = (int)pixels[i];
        pixels[i] = (aux << 8) | (aux >> 24);
    }

}



回答2:


This issue can't be solved in OpenGL ES 1.1 but it would be solvable in OpenGL ES 3.0 or by OpenGL extension EXT_texture_swizzle:

Since OpenGL ES 3.0 you can use the texture swizzle parameters to swap the color channels. See glTexParameter:

GL_TEXTURE_SWIZZLE_R

Sets the swizzle that will be applied to the r component of a texel before it is returned to the shader. Valid values for param are GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_ZERO and GL_ONE. If GL_TEXTURE_SWIZZLE_R is GL_RED, the value for r will be taken from the first channel of the fetched texel. If GL_TEXTURE_SWIZZLE_R is GL_GREEN, the value for r will be taken from the second channel of the fetched texel. ...

This means the color channels will be swapped when the texture is looked up, when you set the following texture parameters to the texture object:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_GREEN);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_BLUE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_ALPHA);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED);


The relevant part in the specification can be found at OpenGL ES 3.0.5 Specification; 3.8.14 Texture State; page 162

To check if an OpenGL extension is valid, glGetString(GL_EXTENSIONS) can be use, which returns a space-separated list of supported extensions.



A completely different solution would be to use a Canvas for the conversion. Draw the Bitmap on the canvas, and then use the target bitmap, which is hold by the canvas.
I found this solution on GitHub: fix android 2.3 can't decode bitmap in rgba8888 format

public static Bitmap convert(Bitmap bitmap, Bitmap.Config config) {
    Bitmap convertedBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), config);
    Canvas canvas          = new Canvas(convertedBitmap);
    Paint  paint           = new Paint();
    paint.setColor(Color.BLACK);
    canvas.drawBitmap(bitmap, 0, 0, paint);
    return convertedBitmap;
}


来源:https://stackoverflow.com/questions/34705921/android-bitmap-pixel-format-for-glteximage2d

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!