Search code examples
c#wpfbitmapcopybitmapsource

fast converting Bitmap to BitmapSource wpf


I need to draw an image on the Image component at 30Hz. I use this code :

public MainWindow()
    {
        InitializeComponent();

        Messenger.Default.Register<Bitmap>(this, (bmp) =>
        {
            ImageTarget.Dispatcher.BeginInvoke((Action)(() =>
            {
                var hBitmap = bmp.GetHbitmap();
                var drawable = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                  hBitmap,
                  IntPtr.Zero,
                  Int32Rect.Empty,
                  BitmapSizeOptions.FromEmptyOptions());
                DeleteObject(hBitmap);
                ImageTarget.Source = drawable;
            }));
        });
    }

The problem is, with this code, My CPU usage is about 80%, and, without the convertion it's about 6%.

So why converting bitmap is so long ?
Are there faster method (with unsafe code) ?


Solution

  • Here is a method that (to my experience) is at least four times faster than CreateBitmapSourceFromHBitmap.

    It requires that you set the correct PixelFormat of the resulting BitmapSource.

    public static BitmapSource Convert(System.Drawing.Bitmap bitmap)
    {
        var bitmapData = bitmap.LockBits(
            new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height),
            System.Drawing.Imaging.ImageLockMode.ReadOnly, bitmap.PixelFormat);
    
        var bitmapSource = BitmapSource.Create(
            bitmapData.Width, bitmapData.Height,
            bitmap.HorizontalResolution, bitmap.VerticalResolution,
            PixelFormats.Bgr24, null,
            bitmapData.Scan0, bitmapData.Stride * bitmapData.Height, bitmapData.Stride);
    
        bitmap.UnlockBits(bitmapData);
    
        return bitmapSource;
    }