How to convert YUV_420_888 image to bitmap [duplicate]
Asked Answered
U

1

2

I am working on AR project where i need to capture the current frame and save it to gallery. I am able to get the image using Frame class in AR core , but the format of image is YUV_420_888. I have already tried lots of solutions to covert this to bitmap but couldn't able to solve it.

Unweave answered 3/1, 2019 at 6:4 Comment(0)
R
5

This is how I convert to jpeg.

public Bitmap imageToBitmap(Image image, float rotationDegrees) {

    assert (image.getFormat() == ImageFormat.NV21);

    // NV21 is a plane of 8 bit Y values followed by interleaved  Cb Cr
    ByteBuffer ib = ByteBuffer.allocate(image.getHeight() * image.getWidth() * 2);

    ByteBuffer y = image.getPlanes()[0].getBuffer();
    ByteBuffer cr = image.getPlanes()[1].getBuffer();
    ByteBuffer cb = image.getPlanes()[2].getBuffer();
    ib.put(y);
    ib.put(cb);
    ib.put(cr);

    YuvImage yuvImage = new YuvImage(ib.array(),
            ImageFormat.NV21, image.getWidth(), image.getHeight(), null);

    ByteArrayOutputStream out = new ByteArrayOutputStream();
    yuvImage.compressToJpeg(new Rect(0, 0,
            image.getWidth(), image.getHeight()), 50, out);
    byte[] imageBytes = out.toByteArray();
    Bitmap bm = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
    Bitmap bitmap = bm;

    // On android the camera rotation and the screen rotation
    // are off by 90 degrees, so if you are capturing an image
    // in "portrait" orientation, you'll need to rotate the image.
    if (rotationDegrees != 0) {
      Matrix matrix = new Matrix();
      matrix.postRotate(rotationDegrees);
      Bitmap scaledBitmap = Bitmap.createScaledBitmap(bm,
              bm.getWidth(), bm.getHeight(), true);
      bitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
              scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
    }
    return bitmap;
  }
Ridglea answered 3/1, 2019 at 18:31 Comment(4)
you said "followed by interleaved Cb Cr", but then you are not actually interleaving them? it seems you are just copying them one after the other, which is not the same as interleavingEpiblast
@AdamBurley That's what I was wondering as well. The only explanation could be is that the compressToJpeg must have all the meat / magic under the hood.Jugglery
@AdamBurley Actually the problem already arises at the very beginning of the procedure image.getFormat() == ImageFormat.NV21. Of course the input us a YUV image, so it poops itself in the beginning at the assert.Jugglery
I only found this blog.csdn.net/weixin_32566515/article/details/114193059Jugglery

© 2022 - 2024 — McMap. All rights reserved.