Search code examples
androidandroid-imageandroid-bitmaparcoresceneform

How to convert YUV_420_888 image to bitmap


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.


Solution

  • 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;
      }