Android- convert ARGB_8888 bitmap to 3BYTE_BGR

六月ゝ 毕业季﹏ 提交于 2021-01-19 05:52:06

问题


I get the pixel data of my ARGB_8888 bitmap by doing this:

public void getImagePixels(byte[] pixels, Bitmap image) {
    // calculate how many bytes our image consists of
    int bytes = image.getByteCount();

    ByteBuffer buffer = ByteBuffer.allocate(bytes); // Create a new buffer
    image.copyPixelsToBuffer(buffer); // Move the byte data to the buffer

    pixels = buffer.array(); // Get the underlying array containing the data.
}

But, I would like to convert this data, in which each pixel is stored on four bytes (ARGB), to where each pixel is stored on 3 bytes (BGR).
Any help is appreciated!


回答1:


Disclaimer: There could be better/easier/faster ways of doing this, using the Android Bitmap API, but I'm not familiar with it. If you want to go down the direction you started, here's your code modified to convert 4 byte ARGB to 3 byte BGR

public byte[] getImagePixels(Bitmap image) {
    // calculate how many bytes our image consists of
    int bytes = image.getByteCount();

    ByteBuffer buffer = ByteBuffer.allocate(bytes); // Create a new buffer
    image.copyPixelsToBuffer(buffer); // Move the byte data to the buffer

    byte[] temp = buffer.array(); // Get the underlying array containing the data.

    byte[] pixels = new byte[(temp.length / 4) * 3]; // Allocate for 3 byte BGR

    // Copy pixels into place
    for (int i = 0; i < (temp.length / 4); i++) {
       pixels[i * 3] = temp[i * 4 + 3];     // B
       pixels[i * 3 + 1] = temp[i * 4 + 2]; // G
       pixels[i * 3 + 2] = temp[i * 4 + 1]; // R

       // Alpha is discarded
    }

    return pixels;
}



回答2:


You can try your skills with a powerful library called OpenCV - and it is free. It allows you to change from BGR to RGB and reverse. It also allows you to add or remove the alpha channel ("A").

OpenCV has a dedicated Android version to download here (OpenCV for Android v 2.4.6).

In this library, check out cvtColor() from this documentation, which states the following:

The function can do the following transformations: Transformations within RGB space like adding/removing the alpha channel, reversing the channel order, conversion to/from 16-bit RGB color (R5:G6:B5 or R5:G5:B5), as well as conversion to/from grayscale [...etc]

I have an app in the Google Play store (UnCanny) that uses OpenCV for Android. It took some time to get up to speed, but has tons of features.




回答3:


With OpenCV library and you getting pixels via different method (see below) you can replace java function with native calls and it is ~4x more fastest:

In summary:

// reading bitmap from java side:
Mat mFrame = Mat(height,width,CV_8UC4,pFrameData).clone();
Mat mout;
cvtColor(mFrame, mout,CV_RGB2GRAY); // or CV_RGB2XXX (3BGR)

Complete example:

Java side:

    Bitmap bitmap = mTextureView.getBitmap(mWidth, mHeight);
    int[] argb = new int[mWidth * mHeight];
    // get ARGB pixels and then proccess it with 8UC4 opencv convertion
    bitmap.getPixels(argb, 0, mWidth, 0, 0, mWidth, mHeight);
    // native method (NDK or CMake)
    processFrame8UC4(argb, mWidth, mHeight);

Native side (NDK):

JNIEXPORT jint JNICALL com_native_detector_Utils_processFrame8UC4
    (JNIEnv *env, jobject object, jint width, jint height, jintArray frame) {

    jint *pFrameData = env->GetIntArrayElements(frame, 0);
    // it is the line:
    Mat mFrame = Mat(height,width,CV_8UC4,pFrameData).clone();
    // the next only is a extra example to gray convertion:
    Mat mout;
    cvtColor(mFrame, mout,CV_RGB2GRAY); // or CV_RGB2XXX
    // your code from here, the next is a example:
    int objects = face_detection(env, mout);
    // release object
    env->ReleaseIntArrayElements(frame, pFrameData, 0);
    return objects;
}


来源:https://stackoverflow.com/questions/18086568/android-convert-argb-8888-bitmap-to-3byte-bgr

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