Jaa


ブログ用 画像ユーティリティ ① 要件と戦略

ブログに写真を載せるとき、VGA程度にサイズを縮小したり、人の顔にモザイクをかけたりすることがよくあります。この程度のことにフォトレタッチ ソフトを買うのはもったいないし、フリーのソフトも複雑で使いにくいので、WPFでシンプルなアプリを書いてみることにしました。

要件は以下のとおりです。

  1. 実行ファイルに画像ファイルをドラッグ&ドロップすると(つまりコマンド オプションとしてファイル名を渡す)、VGAサイズの画像を生成・保存し、終了(表示なし)。
  2. ダブルクリックで起動しウィンドウを開き、画像をウィンドウにドラッグ&ドロップすると、VGAサイズの画像を生成・表示。
  3. 表示画像上でマウス「左ボタン+移動」で、その範囲の画像をモザイク化して表示。
  4. 保存ボタンで画像を保存、保存後終了するかどうかをメッセージボックスで確認。
  5. 画像フォーマットはjpgのみ。
  6. 画像は同じフォルダに保存する。保存するファイル名の先頭に「_」(アンダースコア)を付け、.jpgの前に「VGA」を付ける。(myimage.jpgなら_myimageVGA.jpgとなる)

これを実現するための実装戦略は以下のとおりです。単純に保存ボタンとその下に画像が2つあるだけです。

  1. コマンドライン オプションの実装にはApplication.Startupイベントの記事を利用。
  2. ドラッグ&ドロップの実装にはドロップされたファイルの読み込みのサンプルを利用。
  3. 画像用にコンテナクラスUserControlを作成。ファイル名からVGAサイズのBitmapImageとモザイク用のBitmapImageを生成。エンコードと保存も行う。
    1. VGAサイズ画像(BitmapImage)は、BitmpImage.DecodePixelWidth を指定してBitmapImageを生成。
    2. モザイク画像は、VGA画像をさらに1/20程度に縮小してから、VGAサイズで元のVGA画像の上に表示(以前紹介したNearestNaghborを使えば、モザイク画像になる)。マウスの「左ボタン+移動」で作成した矩形でこの画像をクリップ。なかなか良いアイデア :-)。
    3. この時点では合成されていないので、保存時に合成画像を生成。合成画像を生成するには、RenderTargetBitmap.Renderメソッドに上の2つの画像が乗っているCanvasを渡して、合成ビットマップを生成。WPFは便利!
    4. JpegBitmapEncoderを使ってjpgにエンコードして出力。

すると、XAMLは以下のようになります。保存ボタンの下に、画像が2つ表示されるだけです。

<Window x:Class="ImageShrinker.Window1"
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ImageShrinker"
Title="Image Shrinker" SizeToContent="WidthAndHeight"
AllowDrop="True" PreviewDrop="myImage_Drop"
PreviewDragOver="myImage_PreviewDragOver">
  <Grid Name="myGrid" >
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
      <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <StackPanel Orientation="Horizontal"
Background="LightGray" Grid.Row="0">
      <Button Margin="5,2,0,2" Height="23"
Name="Save" Width="75" Click="Save_Click">
        保存
      </Button>
    </StackPanel>
    <local:VgaImageUC x:Name="myVgaImage" Grid.Row="1" 
MouseLeftButtonDown="Canvas_MouseLeftButtonDown"
MouseMove="Canvas_MouseMove" />
      </Canvas>
    </Border>
  </Grid> |
</Window>

追記:UserControlバージョンに修正