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.
Asked
Active
Viewed 7,244 times
1 Answers
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;
}

Clayton Wilkinson
- 4,524
- 1
- 16
- 25
-
1you 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 interleaving – Adam Burley Jun 30 '21 at 17:10
-
@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. – Csaba Toth Jan 23 '23 at 14:52
-
1@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. – Csaba Toth Jan 23 '23 at 23:42
-
I only found this https://blog.csdn.net/weixin_32566515/article/details/114193059 – Csaba Toth Jan 23 '23 at 23:43