Android- convert ARGB_8888 bitmap to 3BYTE_BGR

后端 未结 3 1284
广开言路
广开言路 2021-01-14 08:03

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 imag         


        
相关标签:
3条回答
  • 2021-01-14 08:33

    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;
    }
    
    0 讨论(0)
  • 2021-01-14 08:42

    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;
    }
    
    0 讨论(0)
  • 2021-01-14 08:46

    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.

    0 讨论(0)
提交回复
热议问题