読者です 読者をやめる 読者になる 読者になる

System.Drawing.Bitmap を System.Windows.Media.Imaging.BitmapSource に変換する

名前空間が長すぎてうんざりしますが、つまりGDI+のBitmapから、WPFBitmapSourceに変換しようということです。

using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using System.Windows.Interop;

class Program
{
    [DllImport("gdi32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool DeleteObject(IntPtr hObject);
 
    static BitmapSource ToBitmapSource(Bitmap bitmap)
    {
        IntPtr ptr = source.GetHbitmap(); 
 
        BitmapSource bs = Imaging.CreateBitmapSourceFromHBitmap(
            ptr, IntPtr.Zero, Int32Rect.Empty, 
            BitmapSizeOptions.FromEmptyOptions()
        );
 
        DeleteObject(ptr);

        return bs;
    }

    static void Main(string[] args)
    {
        // Bitmap -> BitmapSource
        Bitmap bitmap = new Bitmap("hoge.bmp");
        BitmapSource bs = ToBitmapSource(bitmap);

        // 表示してみる
        Image image = new Image { Source = bs };
        Window window = new Window
        {
            Title = "ToBitmapSource sample",
            Width = bs.PixelWidth,
            Height = bs.PixelHeight,
            Content = image
        };

        Application app = new Application();
        app.Run(window);
    }
}

BitmapSourceにはDisposeが無さそうなのでなんか心配になるんですが、メモリの管理の方はどうなっているんでしょうか。

BitmapSourceの具象クラスであるWriteableBitmapを秒間30フレームで生成しまくった時は、そのうちGCが発動してメモリ使用率はのこぎりの歯のようになっていましたので、問題にはならなさそうではあります。とはいえ最近ネイティブを触り続けているせいで明示的に解放しないと落ち着かない性分になっています。なにか明示的に解放する手段はあるんでしょうかね。