I am creating an ImageAnalysis.IAnalyzer and implementing the Analyze method. On Android's documentation at https://developer.android.com/reference/androidx/camera/core/ImageAnalysis.Analyzer#summary https://developer.android.com/reference/androidx/camera/core/ImageProxy#toBitmap() It says that the parameter is of type ImageProxy which contains a method toBitmap() . However, when doing it in Xamarin.Android & C#, the parameter is of type IImageProxy , and therefore does not seem to have a toBitmap() method. IImageProxy has a property Image of type Android.Media.Image . However, I cannot seem to find a way to convert from Android.Media.Image to Android.Graphics.Bitmap . Everything I have been able to find seems to involve manually converting by use of Byte Arrays. Is there any easier way to do this, or any utility classes that can be used for this?

Hello,

Is there any easier way to do this, or any utility classes that can be used for this?

I cannot find eaisier way to do this, I search for Android.Util api, I cannot find related api to do this. You can create method and convert image to bitmap like following code.

public Bitmap ConvertImageToBitMap(Android.Media.Image image)
            ByteBuffer buffer = image.GetPlanes()[0].Buffer;
            byte[] bytes = new byte[buffer.Capacity()];
            buffer.Get(bytes);
            Bitmap bitmapImage = BitmapFactory.DecodeByteArray(bytes, 0, bytes.Length, null);
            return bitmapImage;

========Update=====

Please check the image's format to see if it is ImageFormat.YUV_420_888, if so, please use following code to transfer it.

public Bitmap ConvertImageToBitMap(Android.Media.Image image)
            ByteBuffer yBuffer = image.GetPlanes()[0].Buffer; //y
            ByteBuffer vuBuffer = image.GetPlanes()[2].Buffer; //vu
            int ySize = yBuffer.Remaining();
            int vuSize = vuBuffer.Remaining();
            byte[] nv21 = new byte[ySize + vuSize];
            yBuffer.Get(nv21, 0, ySize);
            vuBuffer.Get(nv21, ySize, vuSize);
            YuvImage yuvImage = new YuvImage(nv21, ImageFormatType.Nv21, image.Width, image.Height, null);
            System.IO.MemoryStream outstream = new System.IO.MemoryStream();
            yuvImage.CompressToJpeg(new Rect(0, 0, yuvImage.Width, yuvImage.Height), 50, outstream);
            byte[] imagebytes = outstream.ToArray();
            Bitmap bitmapImage = BitmapFactory.DecodeByteArray(imagebytes, 0, imagebytes.Length, null);
            return bitmapImage;

Best Regards, Leon Lu

If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment". Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

I tried creating the following Extension Method:

public static Bitmap ToBitmap(this Image img)
	ByteBuffer buffer = img.GetPlanes()[0].Buffer;
	byte[] bytes = new byte[buffer.Capacity()];
	buffer.Get(bytes);
	return BitmapFactory.DecodeByteArray(bytes, 0, bytes.Length, null);

However, even though img is not null, the Extension Method is returning null. Is there something wrong with my method?

I don't quite understand what you are saying. I can add the Breakpoint, but what do you mean by

then debug it, which line is empty

I don't get any Exceptions inside this method, I don't get an Exception until I attempt to use the Bitmap returned from the method (obviously because it is a null Bitmap).

While looking at the Android documentation at: https://developer.android.com/reference/androidx/camera/core/ImageProxy#getImage() I noticed that it says the following:

It is possible for an ImageProxy to wrap something that isn't an Image. If that's the case then it will return null.

Is it possible that this is possible or related to my problem? Even though I have confirmed that Image is not null, I have not (and am not sure how I would) confirmed that it really is an Image (I don't know why it wouldn't be, but there is obviously a lot I don't know). Is it possible that something related to this is causing the problem?

I was looking at the following page: https://social.msdn.microsoft.com/Forums/en-US/feff567e-4ca9-4e46-960e-51d98964bd6f/bitmap-decode-byte-array-skia-decoder-returns-false?forum=xamarinandroid And at the end it mentions missing byte(s) at the end of the byte[]. I tried modifying my code to the following:

buffer.Get(bytes);
bytes = bytes.Concat(new byte[] { (byte)0xFF, (byte)0xD9 }).ToArray();
return BitmapFactory.DecodeByteArray(bytes, 0, bytes.Length, null);

As well as adding the following to the Builder for my ImageAnalysis:

.SetOutputImageFormat(ImageAnalysis.OutputImageFormatRgba8888)

However, neither of these seemed to make any difference. Are they possible factors?

Please check the image's format to see if it is ImageFormat.YUV_420_888

ImageFormatType formatType=image.Format;
            if (formatType.Equals(ImageFormatType.Yuv420888))

If the format is ImageFormat.YUV_420_888, please use my updated answer code to convert it.

For anybody who wants it, here is the final Extension Method I wrote based on the code above:

public static Bitmap ToBitmap(this Image img)
	ByteBuffer ybuffer = img.GetPlanes()[0].Buffer;
	ByteBuffer vubuffer = img.GetPlanes()[2].Buffer;
	ybuffer.Position(0);
	vubuffer.Position(0);
	int ysize = ybuffer.Remaining();
	int vusize = vubuffer.Remaining();
	byte[] nv21 = new byte[ysize + vusize];
	ybuffer.Get(nv21, 0, ysize);
	vubuffer.Get(nv21, ysize, vusize);
	YuvImage yuvimage = new YuvImage(nv21, ImageFormatType.Nv21, img.Width, img.Height, null);
	MemoryStream outstream = new MemoryStream();
	yuvimage.CompressToJpeg(new Rect(0, 0, yuvimage.Width, yuvimage.Height), 50, outstream);
	byte[] imagebytes = outstream.ToArray();
	return BitmapFactory.DecodeByteArray(imagebytes, 0, imagebytes.Length, null);