Converting from Android.Media.Image to Android.Graphics.Bitmap

Nathan Sokalski 4,111 Reputation points
2023-04-04T22:44:33.88+00:00

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?

Developer technologies .NET Xamarin
Developer technologies .NET Other
Developer technologies C#
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Anonymous
    2023-04-05T01:40:40.1466667+00:00

    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.


  2. Nathan Sokalski 4,111 Reputation points
    2023-04-17T01:04:38.69+00:00

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

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.