Convert bitmap array to YUV (YCbCr NV21)

rgb to yuv converter
rgb to nv21
yuv_420_888 to nv21
yuv422 format
yv12
yuv file format
opencv nv21
bitmap to nv12

How to convert Bitmap returned by BitmapFactory.decodeFile() to YUV format (simillar to what camera's onPreviewFrame() returns in byte array)?

Here is some code that actually works:

    // untested function
    byte [] getNV21(int inputWidth, int inputHeight, Bitmap scaled) {

        int [] argb = new int[inputWidth * inputHeight];

        scaled.getPixels(argb, 0, inputWidth, 0, 0, inputWidth, inputHeight);

        byte [] yuv = new byte[inputWidth*inputHeight*3/2];
        encodeYUV420SP(yuv, argb, inputWidth, inputHeight);

        scaled.recycle();

        return yuv;
    }

    void encodeYUV420SP(byte[] yuv420sp, int[] argb, int width, int height) {
        final int frameSize = width * height;

        int yIndex = 0;
        int uvIndex = frameSize;

        int a, R, G, B, Y, U, V;
        int index = 0;
        for (int j = 0; j < height; j++) {
            for (int i = 0; i < width; i++) {

                a = (argb[index] & 0xff000000) >> 24; // a is not used obviously
                R = (argb[index] & 0xff0000) >> 16;
                G = (argb[index] & 0xff00) >> 8;
                B = (argb[index] & 0xff) >> 0;

                // well known RGB to YUV algorithm
                Y = ( (  66 * R + 129 * G +  25 * B + 128) >> 8) +  16;
                U = ( ( -38 * R -  74 * G + 112 * B + 128) >> 8) + 128;
                V = ( ( 112 * R -  94 * G -  18 * B + 128) >> 8) + 128;

                // NV21 has a plane of Y and interleaved planes of VU each sampled by a factor of 2
                //    meaning for every 4 Y pixels there are 1 V and 1 U.  Note the sampling is every other
                //    pixel AND every other scanline.
                yuv420sp[yIndex++] = (byte) ((Y < 0) ? 0 : ((Y > 255) ? 255 : Y));
                if (j % 2 == 0 && index % 2 == 0) { 
                    yuv420sp[uvIndex++] = (byte)((V<0) ? 0 : ((V > 255) ? 255 : V));
                    yuv420sp[uvIndex++] = (byte)((U<0) ? 0 : ((U > 255) ? 255 : U));
                }

                index ++;
            }
        }
    }

Convert bitmap array to YUV (YCbCr NV21), How to convert Bitmap returned by BitmapFactorydecodeFile to YUV format simillar to what cameras onPreviewFrame returns in byte array Questions: How to convert Bitmap returned by BitmapFactory.decodeFile() to YUV format (simillar to what camera’s onPreviewFrame() returns in byte array)? How to&Answers: Here is some code that actually works: // untested function byte [] getNV21(int inputWidth, int inputHeight, Bitmap scaled) { int [] argb = new int[inputWidth * inputHeight]; scaled.getPixels(argb, 0, inputWidth, 0, 0

Following is the code for converting Bitmap to Yuv(NV21) Format.

void yourFunction(){

    // mBitmap is your bitmap

    int mWidth = mBitmap.getWidth();
    int mHeight = mBitmap.getHeight();

    int[] mIntArray = new int[mWidth * mHeight];

    // Copy pixel data from the Bitmap into the 'intArray' array
    mBitmap.getPixels(mIntArray, 0, mWidth, 0, 0, mWidth, mHeight);

    // Call to encoding function : convert intArray to Yuv Binary data
    encodeYUV420SP(data, intArray, mWidth, mHeight);

}

static public void encodeYUV420SP(byte[] yuv420sp, int[] rgba,
        int width, int height) {
    final int frameSize = width * height;

    int[] U, V;
    U = new int[frameSize];
    V = new int[frameSize];

    final int uvwidth = width / 2;

    int r, g, b, y, u, v;
    for (int j = 0; j < height; j++) {
        int index = width * j;
        for (int i = 0; i < width; i++) {

            r = Color.red(rgba[index]);
            g = Color.green(rgba[index]);
            b = Color.blue(rgba[index]);

            // rgb to yuv
            y = (66 * r + 129 * g + 25 * b + 128) >> 8 + 16;
            u = (-38 * r - 74 * g + 112 * b + 128) >> 8 + 128;
            v = (112 * r - 94 * g - 18 * b + 128) >> 8 + 128;

            // clip y
            yuv420sp[index] = (byte) ((y < 0) ? 0 : ((y > 255) ? 255 : y));
            U[index] = u;
            V[index++] = v;
        }
    }

Android---Bitmap(argb_8888) to NV21, Convert NV21 data to BMP files purely in Java. NV21 is a kind of YUV (also be referred to as YCbCr) format used for images. To save RGB array to an image, you can simply use Java Class BufferedImage and ImageIO: Convert bitmap array to YUV (YCbCr NV21) Posted by: admin February 23, 2018 Leave a comment. Following is the code for converting Bitmap to Yuv(NV21) Format.

If using java to convert Bitmap to YUV byte[] is too slow for you, you can try libyuv by Google

How to Convert NV21 Data to BMP File in Java, YUV is a color encoding system typically used as part of a color image pipeline. It encodes a The scope of the terms Y′UV, YUV, YCbCr, YPbPr, etc., is sometimes or YV12) to RGB888 conversion; 7.5 Y′UV420sp (NV21) to RGB conversion (Android) Inverting the above transformation converts Y′UV to RGB:. Home > android - Convert bitmap array to YUV (YCbCr NV21) show 5 more comments up vote 3 down vote Following is the code for converting Bitmap to Yuv(NV21) Format

Via OpenCV library you can replace encodeYUV420SP java function with one native OpenCV line and it is ~4x more fastest:

Mat mFrame = Mat(height,width,CV_8UC4,pFrameData).clone();

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);
    int objects = face_detection(env, mout);
    env->ReleaseIntArrayElements(frame, pFrameData, 0);
    return objects;
}

YUV, AndroidBitmapInfo bitmapInfo; uint32_t* bitmapContent; < 0) abort(); // Accesses source array data. jbyte* source = (*pEnv)->GetPrimitiveArrayCritical(​pEnv, pSource, 0); if (source == NULL) abort(); 3. YCbCr 420 SP (or NV21) format. The following algorithm processes each pixel and converts each YUV pixel to RGB  Recommend:android - Convert bitmap array to YUV (YCbCr NV21) what camera's onPreviewFrame() returns in byte array) android image-processing android-camera yuv android-image share | improve this question edited May 11 '11 at 7:29 asked May 11 '11 at 6:40 Abhijeet Pathak 1,095 2 12 28 add a comment

The bmp file will be in RGB888 format, so you will need to convert it to YUV. I have not come across any api in Android that will do this for you.

But you can do this yourself, see this link on how to..

Android NDK: Beginner's Guide, information about color formats, take a look into the following places: FOURCC YUV pixel formats list. YUV color space. RGB color space. YCbCr color space. The YUV byte[] will have gray image in the first width*height bytes and color information next. For processing preview image without taking picture from Camera using Camera.takePicture method, mostly we need to convert the YUV byte[] into a Bitmap.

RAW Pixels, Android convert ImageReader Image to YCbCr_420_SP (NV21) byte array using render script? - android. Convert bitmap array to YUV (YCbCr NV21). How to  Confusion on YUV NV21 conversion to RGB. Thanks for contributing an answer to Stack Overflow! Convert bitmap array to YUV (YCbCr NV21) 9.

Android convert ImageReader Image to YCbCr_420_SP (NV21 , There are many frames available whoseformat isbased on YUV colors. Here,we convertframes followingthe YCbCr 420 SP (or NV21)format. unlocking the backbuffer bitmapand releasing theJava array acquired earlier: int32_t lFrameSize  Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information. Convert bitmap array to YUV (YCbCr NV21) 9. int array

Android NDK: Discover the Native Side of Android and Inject the , NV21 is a kind of YUV (also be referred to as YCbCr) format used for images. It has one luminance plane Y and one plane with V and U values interleaved. For a 2×2 group of pixels, you have 4 Y samples and 1 V and 1 U sample:

Comments
  • Thanks! I'll try it and let you know.
  • If anyone needs YV12 instead of NV21, this answer can be modified slightly to produce everyone's favorite tri-planar format instead: gist.github.com/wobbals/5725412
  • According to yuv420sp spec, the U-value is stored before V in the last 3rd of the buffer, so I had to swap the rows inside the if-case to prevent blue/reds from being flipped.
  • I had problems using this method on a bitmap from BitmapFactory.decodeResource(), but it works fine when I instead load the bitmap from BitmapFactory.decodeStream(getAssets().open("myasset.bmp")).
  • encodeYUV420SP throws ArrayIndexOutOfRange Exception when inputWidth or inputHeight is an odd number. Declaring the yuv array as byte [] yuv = new byte[inputHeight * inputWidth + 2 * (int) Math.ceil(inputHeight/2.0) *(int) Math.ceil(inputWidth/2.0)]; solved the issue.
  • tried it, but came to an ArrayIndexOutOfBoundsException in line r = (rgba[index] & 0xff000000) >> 24;
  • This code is highly inefficient.Better avoid this code.
  • Please provide an actual answer rather than linking to content. Links can become outdated.
  • This hardly answers anything, how the data is packed in not explained.