F#からWPFのGUIを扱う その4
前回(F#からWPFのGUIを扱う その3)の別解として、今度は Win32 API を直接利用せずにインターフェイス IValueConverter の実装を別の方法で試みます。
MyBitmapConverter クラスを再実装します。よって、前回のF#のコードの34~52行目を以下のコードで置き換えます。
- [<System.Windows.Data.ValueConversion(typeof<System.Drawing.Bitmap>, typeof<System.Windows.Media.ImageSource>)>]
- type MyBitmapConverter() =
- interface System.Windows.Data.IValueConverter with
- override x.Convert(value: obj, targetType: System.Type, parameter: obj, culture: System.Globalization.CultureInfo) =
- let drawingBmp = value :?> System.Drawing.Bitmap
- assert(not <| obj.ReferenceEquals(drawingBmp, null))
- // ビットマップからピクセルデータ取り出し
- let bmpData: System.Drawing.Imaging.BitmapData =
- drawingBmp.LockBits(
- System.Drawing.Rectangle(System.Drawing.Point(0, 0), drawingBmp.Size),
- System.Drawing.Imaging.ImageLockMode.ReadOnly,
- drawingBmp.PixelFormat)
- let scanLineWidth = abs(bmpData.Stride) // Strideプロパティが負の場合にも対処
- let buffSize = scanLineWidth * drawingBmp.Height
- use graphics = System.Drawing.Graphics.FromImage(drawingBmp)
- // BGRの順にデータが並んでいるので注意
- let bmpSrc = System.Windows.Media.Imaging.BitmapSource.Create(
- drawingBmp.Width,
- drawingBmp.Height,
- double graphics.DpiX,
- double graphics.DpiY,
- System.Windows.Media.PixelFormats.Bgr24,
- null,
- bmpData.Scan0,
- buffSize,
- scanLineWidth)
- bmpSrc.Freeze()
- drawingBmp.UnlockBits(bmpData)
- bmpSrc :> obj
- override x.ConvertBack(value: obj, targetType: System.Type, parameter: obj, culture: System.Globalization.CultureInfo) =
- failwith("not implemented")
内部実装は変えましたが 実行結果は前回と同じ外観です。