はじめに
「Windows phoneで画像エフェクトアプリを作ろう!」の2回目では、エフェクト処理の高速化、リサイズ、画像の保存の仕方を取り扱います。
エフェクト処理の高速化と、元の画像の縦横比を保ったままWindows phoneの画面に収まる形にリサイズする方法、エフェクト処理した後の画像を保存する方法を取り上げたいと思います。サンプルプログラムを用意していますのでどうぞご利用ください。
エフェクト処理の高速化を行う
前回のさいごにBitmap.SetPixelメソッドとGetPixelメソッドが遅い理由にアンマネージド領域へアクセスするオーバーヘッドのためと書かせて頂きました。480ピクセル×640ピクセルのVGA画像の場合で307,200回アクセスして読み込み、書き込みするのに同じだけのアクセスが発生します。
LockBitsメソッドを使うと、ピクセル配列にアンマネージドメモリのBitmapデータをマーシャリングでコピーしエフェクト処理を行い、処理後のピクセル配列で元のBitmapデータに置き換えることができます。配列へのアクセスだけでエフェクト処理を行いますので、Bitmapへのアクセスに比べ高速に行うことができます。
Image.PixelFormatプロパティが.NET Compact Frameworkではサポートされていませんので、Bitmap.LockBitsメソッドで指定するピクセル形式を明示的に指定する必要があります。ここではPixelFormat.Format24bppRgbを指定しています。
適度なサイズの画像でSetPixel/GetPixelが極端に遅い場合、Debugモードが原因かもしれませんので、一度Releaseモードで確かめてみるのも有りだと思います。
写真全体を表示可能な様に縦横比を合わせてリサイズする
技術の進歩とともに撮影可能なサイズは増加の一方です。国内で発売された中で一番大きなディスプレイを持つ端末でもFVGA(480×853)ですので、写真撮影できるWindows phoneのすべてがディスプレイより大きなサイズの写真を撮ることができます。
大きな写真の全体像をディスプレイに表示するには、PictureBoxのSizeModeプロパティをImageSize.Stechに設定するのが簡単ですが、写真をPictureBoxのサイズに合わせてしまいますので縦横比が崩れて(Windows phoneを縦にしていれば縦長に、横にしていれば横長にリサイズされて)しまいます。
デスクトップ版の.NET Frameworkでは、SizeModeプロパティにImageSize.Zoomを設定すると縦横比を保ったままきちんとリサイズして表示されるのですが、.NET Compact Frameworkにはその定義が存在しません。GraphicsのDrawImageメソッドを用いて縦横比を保ったままリサイズするコードを書きましょう。
写真のサイズが表示すべき領域より大きい場合のみリサイズを行うResizeBitmapメソッドを以下に示します。
作成したResizeBitmapメソッドを利用方法を示します。このアプリケーションPictureEffectでは、「選択」ボタンが押下されるとmenuSelectPicture_Clickメソッドを実行します。
this.OriginalBmpに格納したBitmapをPictureBoxに表示していますので、this.OriginalBmpにBitmapを格納する前にResizeBitmapメソッドを使ってリサイズ処理を行います。
加工した画像を保存する
せっかくですのでエフェクトをかけた画像を保存してみましょう。BitmapクラスにはSaveメソッドが用意されています。これで指定したファイルパスやストリームに画像を保存することが可能です。
MainMenuに「保存」を追加しました。保存ボタンを押下すると、SaveFileDialogのFileNameプロパティから保存先のファイルパスを取得し、pictureBox1にて表示しているImageをファイルとして画像保存します。
上記のコードではImageFormat.Jpegを指定してJPEG形式にて保存をしていますが、ほかにもBitmap、PNG、GIFで保存することができます。
画像を転送する場合などストリームで保存するほうが都合のよい時は、第1引数のString型のファイルパスの代わりに、System.IO名前空間のMemoryStreamクラス等を指定しましょう。MemoryStreamを使用する場合場合のコードを以下に示します。
さいごに
連載第8回、9回と使って紹介させて頂いた「Windows phoneで画像エフェクトアプリの作り方」も一旦終わりです。
エフェクトを掛けた後の画像をflickrやTumblrなどのフォトストレージサービスのWebAPIを使ってシェアすると、ネットに常時接続されたモバイルならではの特徴を生かしたアプリケーションになると思います。興味を持たれた方は一度挑戦してみてください。
今回は以上で終わりです。ありがとうございました。