nuits.jp blog

C#, Xamarin, WPFを中心に書いています。Microsoft MVP for Development Technologies。

WPFでの画像処理の基本

WPFではそれまでのWinFormsとは違い、WICベースのImageSourceクラスやBitmapImageクラスなどを利用して画像処理を行います。

Windows Imaging Component - Wikipedia

ただ、あまり情報が少ないというか、「.NETで画像処理=System.Drawing」な情報ばかりでてくるので自分のためにも基本処理をまとめておきたいと思います。

イメージの読み込み

注意点は最後のFreeze呼び出しです。 バックグラウンドで前述の処理をした場合、Freezeしなかった場合にリソースがリークします。

フォーマットを指定したイメージの読み込み

前述のコードだと、例えば
「システムではjpegだけサポートするため、ファイル選択ダイアログでjpegに絞っていたのに、実はpngで拡張子が変更されていた」
といったケースでも読み取れてしまいます。
以下のように直接デコーダーを指定することで、対象外の意図しないデコードを防ぐことが可能です。

イメージの書き込み

以下はJpeg形式で保管するイメージです。
他の形式も該当するEncoderを利用することで保存可能です。
拡張メソッドの形式で記載しています。

この方式にはSystem.Drawingにはないメリットがありまして、色震度が8bitのJpegへの保管などが可能です。

イメージの変形

回転や拡大縮小などです。
画面上で回転や拡大縮小したいだけであればこの方法ではなく、WPFの表示側で制御したほうが良いでしょう。
この方法はバイト列として保管したい場合などに利用します。
以下には回転と拡大縮小だけのせますが、他にも以下のTransformクラスの実装クラスがあります。

  • System.Windows.Media.MatrixTransform
  • System.Windows.Media.RotateTransform
  • System.Windows.Media.ScaleTransform
  • System.Windows.Media.SkewTransform
  • System.Windows.Media.TransformGroup
  • System.Windows.Media.TranslateTransform

回転

90度単位の回転処理です。
細かい角度での回転はSkewTransformを使うのだと思います。(みてません)

拡大縮小

DPIを維持したまま変形したい

前述のコードだと、オリジナルのDPIが失われて「たぶん」ディスプレイのDPIで画像が作成されてしまいます。
しかも後から変更できませんてことで、以下の対応をしていますが、ほかにもっといい方法ないのかなぁ。。。

ひとまず以上です。