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

亀岡的プログラマ日記

京都のベッドタウン、亀岡よりだらだらとお送りいたします。

System.Drawing.BitmapをSystem.Windows.Media.BitmapSourceにWin32無しで変換する。

つまり、WindowsFormのBitmapをWPFから使う方法ですね。

あんまり使う機会がないとおもいきや、私は結構システムリソースの中にBitmapを保存して管理したいなぁ、と思ってしまう人なので(構文チェック効きますし)、そんな時になんだかなぁと困っていたのです。

当然この問題には典型的な解法があります。こんなんです。

CreateBitmapSourceFromHBitmapというメソッドを用意するならHBitmapを削除する術もネイティブに用意しておいてくれよう・・・とは思いますが。(Marshal名前空間でいいからさ!)

ちなみに上記は地味に拡張メソッドになってるのでこんなふうに使えるはず。

BitmapSource imageSource = Properties.Resources.SomePicture.ToWPFBitmap();

これでまぁ一息、なのですが。
こんな記事が有りまして。

これはメモリストリーム上に一旦画像ファイルとして展開して、それを再度読み込む、という形で割かし強引に実現しています。
しかしながらWritableBitmapを提供するためにはUIスレッドが必要という割と諸刃の剣。んで、そのコメントの中にですね。

Another option for the threading issue would be to put the CreateBitmapSourceFromBitmap logic inside a ValueConverter so a Binding can point to a Bitmap and the ValueConverter would turn it into a BitmapSource and it would all be done in the UI thread.
In fact, that is the way I'm doing this.

http://www.codeproject.com/Articles/104929/Bitmap-to-BitmapSource?msg=3586368#xx3586368xx

あぁそうか。Converter書いときゃいいよね!そりゃそうだ。UIスレッドが呼ぶものだし。

というわけでこんな感じに。

使うときはこんな感じ。

<Image Source="{Binding BitmapImage, Converter={StaticResource WinFormBitmapConverter}, Mode=OneWay}"/>

ちなみに速度はWin32使った方が速かった。100個くらいの変換で3倍程度、100msecくらいの差がでますねー。