简体   繁体   English

Android-将ARGB_8888位图转换为3BYTE_BGR

[英]Android- convert ARGB_8888 bitmap to 3BYTE_BGR

I get the pixel data of my ARGB_8888 bitmap by doing this: 通过执行以下操作,我得到了ARGB_8888位图的像素数据:

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 ). 但是,我想将每个像素存储在四个字节(ARGB)中的数据转换为每个像素存储在3个字节( BGR )中的数据。
Any help is appreciated! 任何帮助表示赞赏!

Disclaimer: There could be better/easier/faster ways of doing this, using the Android Bitmap API, but I'm not familiar with it. 免责声明:使用Android Bitmap API可能会有更好/更轻松/更快的方法,但是我对此并不熟悉。 If you want to go down the direction you started, here's your code modified to convert 4 byte ARGB to 3 byte BGR 如果您想沿着开始的方向前进,请修改以下代码,将4字节ARGB转换为3字节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;
}

You can try your skills with a powerful library called OpenCV - and it is free. 您可以使用名为OpenCV的强大库来尝试您的技能-它是免费的。 It allows you to change from BGR to RGB and reverse. 它允许您从BGR更改为RGB,然后反转。 It also allows you to add or remove the alpha channel ("A"). 它还允许您添加或删除Alpha通道(“ A”)。

OpenCV has a dedicated Android version to download here (OpenCV for Android v 2.4.6) . OpenCV有专用的Android版本可在此处下载(适用于Android v.4.6的OpenCV)

In this library, check out cvtColor() from this documentation , which states the following: 在该库中,从本文档中检查cvtColor() ,其中指出以下内容:

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] 该函数可以执行以下转换:在RGB空间内进行转换,例如添加/删除alpha通道,反转通道顺序,与16位RGB颜色(R5:G6:B5或R5:G5:B5)之间的转换。作为与灰度之间的转换[...等]

I have an app in the Google Play store ( UnCanny ) that uses OpenCV for Android. 我在Google Play商店( UnCanny )中有一个使用Android OpenCV的应用程序。 It took some time to get up to speed, but has tons of features. 它花了一些时间来加快速度,但具有大量功能。

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 : 使用OpenCV库,您可以通过不同的方法获取像素(请参见下文),您可以将Java函数替换为本地调用,并且速度要快约4倍

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: Java方面:

    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): 本机端(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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM