How to convert ImageSource to Bitmap?

AndreyZhukovAndreyZhukov USMember ✭✭

I found an example, but this example uses the "Int32Rect", class of System.Windows, we can't use this library for android or ios
For bitmap, i use the System.Drawing.Common

public static System.Drawing.Bitmap BitmapSourceToBitmap2(BitmapSource srs)
        {
            int width = srs.PixelWidth;
            int height = srs.PixelHeight;
            int stride = width * ((srs.Format.BitsPerPixel + 7) / 8);
            IntPtr ptr = IntPtr.Zero;
            try
            {
                ptr = Marshal.AllocHGlobal(height * stride);
                srs.CopyPixels(new Int32Rect(0, 0, width, height), ptr, height * stride, stride);
                using (var btm = new System.Drawing.Bitmap(width, height, stride, System.Drawing.Imaging.PixelFormat.Format1bppIndexed, ptr))
                {
                    // Clone the bitmap so that we can dispose it and
                    // release the unmanaged memory at ptr
                    return new System.Drawing.Bitmap(btm);
                }
            }
            finally
            {
                if (ptr != IntPtr.Zero)
                    Marshal.FreeHGlobal(ptr);
            }
        }

So, how to convert ImageSource to Bitmap for cross-platform project?

Answers

  • jezhjezh Member, Xamarin Team Xamurai

    You can try the following methods:

     public static BitmapSource ConvertBitmap(Bitmap source)
      {
          return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                   source.GetHbitmap(),
                  IntPtr.Zero,
                  Int32Rect.Empty,
                  BitmapSizeOptions.FromEmptyOptions());
        }
    
      public static Bitmap BitmapFromSource(BitmapSource bitmapsource)
      {
        Bitmap bitmap;
        using (var outStream = new MemoryStream())
       {
          BitmapEncoder enc = new BmpBitmapEncoder();
          enc.Frames.Add(BitmapFrame.Create(bitmapsource));
          enc.Save(outStream);
          bitmap = new Bitmap(outStream);
        }
       return bitmap;
       }
    

    For more details: https://stackoverflow.com/questions/2284353/is-there-a-good-way-to-convert-between-bitmapsource-and-bitmap

  • AndreyZhukovAndreyZhukov USMember ✭✭

    @jezh said:
    You can try the following methods:

     public static BitmapSource ConvertBitmap(Bitmap source)
      {
          return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                   source.GetHbitmap(),
                  IntPtr.Zero,
                  Int32Rect.Empty,
                  BitmapSizeOptions.FromEmptyOptions());
        }
    
      public static Bitmap BitmapFromSource(BitmapSource bitmapsource)
      {
        Bitmap bitmap;
        using (var outStream = new MemoryStream())
       {
          BitmapEncoder enc = new BmpBitmapEncoder();
          enc.Frames.Add(BitmapFrame.Create(bitmapsource));
          enc.Save(outStream);
          bitmap = new Bitmap(outStream);
        }
       return bitmap;
       }
    

    For more details: https://stackoverflow.com/questions/2284353/is-there-a-good-way-to-convert-between-bitmapsource-and-bitmap

    This methods again use "Int32Rect" from windows library, I think it will not work for Android and iOS

    It also raises the question of which libraries the following classes "BitmapEncoder","BitmapSizeOptions". System.Drawing.Common does not know such classes

  • AndreyZhukovAndreyZhukov USMember ✭✭
    edited March 11

    I tried to follow guide, there was incomplete information in it and I tried to fill in the understatement on my own

    The project even compiles! However, when I try to get the result from the GetBitmapFromImageSourceAsync (…) method, the application freezes (infinite loop)

    var test = GetBitmapFromImageSourceAsync(image, Android.App.Application.Context);
    var bitmap = test.Result;
    

    Please see why it does not work? Or please give me a link to your project and I’ll figure it out

    https://github.com/StriBog45/XamarinImage

Sign In or Register to comment.