連載:Silverlight 3実践プログラミング

SaveFileDialogとBitmap API

シグマコンサルティング 菅原 英治
2009/10/20
Page1 Page2

サンプル・アプリのソース・コード解説

サンプル・アプリのソース・コード

 今回は、サンプル・アプリのソース・コードをあらかじめ用意しました。次のリンクからZIPファイルでダウンロードできます。

【ソース・コードのリンク】

ソースの解説

 それでは、ソースを解説します。繰り返しになりますが、本稿は、SaveFileDialogとBitmap APIがテーマであるので、それを利用している[落書きを保存]ボタン・クリック時の処理を中心に解説します。

 まず次のコードは、[落書きを保存]ボタンに対するClickイベント・ハンドラのコードです。

' 保存ボタンをクリックしたときの処理です
Private Sub savePaint_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)

  ' SaveFileDialogを開きます
  Dim saveDialog As New SaveFileDialog() With { _
    .DefaultExt = "bmp", _
    .Filter = "ビットマップ(*.bmp)|*.bmp" _
  }

  If saveDialog.ShowDialog() = True Then

    ' ファイルの保存するためのストリームを開きます
    Using stream As Stream = saveDialog.OpenFile()

      ' 画像を取り込んだInkPresenterを対象に
      ' WriteableBitmapオブジェクトを生成します
      Dim wb As New WriteableBitmap(Me.inkP, Nothing)

      ' WriteableBitmapオブジェクトから
      ' 出力用のバイト配列を取得します
      Dim buffer As Byte() = GetBuffer(wb)

      ' Bitmapファイルとして保存します
      stream.Write(buffer, 0, buffer.Length)
    End Using
  End If
End Sub
// 保存ボタンをクリックしたときの処理です
private void savePaint_Click(object sender, RoutedEventArgs e)
{
  // SaveFileDialogを開きます
  SaveFileDialog saveDialog = new SaveFileDialog() {
    DefaultExt = "bmp",
    Filter = "ビットマップ(*.bmp)|*.bmp"
  };

  if (saveDialog.ShowDialog() == true)
  {
    // ファイルの保存するためのストリームを開きます
    using (Stream stream = saveDialog.OpenFile())
    {

      // 画像を取り込んだInkPresenterを対象に
      // WriteableBitmapオブジェクトを生成します
      WriteableBitmap wb = new WriteableBitmap(this.inkP, null);

      // WriteableBitmapオブジェクトから
      // 出力用のバイト配列を取得します
      byte[] buffer = GetBuffer(wb);

      // Bitmapファイルとして保存します
      stream.Write(buffer, 0, buffer.Length);
    }
  }
}
[落書きを保存]ボタン・クリック時の処理(上:MainPage.xaml.vb、下:MainPage.xaml.cs)

 このコードのポイントを解説していきましょう。

SaveFileDialogクラスの利用

 まず、1つ目のポイントは、SaveFileDialogクラス(System.Windows.Controls名前空間)です。SaveFileDialogクラスを利用すると、サンプルで実感していただいたとおり、ファイルを保存するダイアログ(=[開く]ダイアログ)が利用できます。このとき、DefaultExtプロパティで保存する際のファイルの拡張子を指定したり、Filterプロパティでファイルの種類を指定したりすることが可能です。

 ShowDialogインスタンス・メソッドを呼び出すと、ファイルを保存するダイアログ(=[名前を付けて保存]ダイアログ)を表示します。ダイアログにて、[保存]ボタンがクリックされたかどうかは、そのメソッドがtrueを返すかどうかで判定できます。

 そして、OpenFileインスタンス・メソッドを呼び出すと、ファイルを保存するためのStreamインスタンス(System.IO名前空間)を生成することができます。サンプルではそれを利用しビットマップ・ファイルを書き出していますが、それに限らずテキスト・ファイルはもちろん任意のファイルを書き出すことが可能です。

WriteableBitmapクラスの利用

 続いて、次のポイントは、Bitmap APIとして提供されたWriteableBitmapクラス(System.Windows.Media.Imaging名前空間)です。WriteableBitmapクラスを利用すると、Silverlightアプリ上に表示している要素(=UIElementオブジェクト)をビットマップとして取得できます。

 サンプルでは、落書きを描いたInkPresenterオブジェクト(System.Windows.Controls名前空間)を対象にWriteableBitmapクラスのインスタンスを生成し、落書きされた画像のビットマップを取得しています。

 上記のコードにはありませんが、WriteableBitmapインスタンスのPixelsプロパティを利用することで、ビットマップのデータにアクセスすることができます。本稿では、簡単のためPixelsプロパティを利用する際のコードは解説しませんが(サンプルのGetBufferメソッドで実装しています)、ご興味のある方は上述のソースをダウンロードすることでご確認いただけます。

 ビットマップのPixelsプロパティを利用して、ビットマップ・ファイルを保存するためのバッファを作成したら、それをSaveFileDialogオブジェクトのOpenFileメソッドで生成したStreamオブジェクトのWriteメソッドで出力すれば、ビットマップ(.bmp)ファイルとして保存されます。

【コラム】.pngファイルで保存したい

 すでにお気づきの方もいらっしゃるかも知れませんが、本稿のサンプルには致命的な欠点があります。それは、.bmpファイルとして保存した画像は、Silverlightが対応する画像のフォーマットが.jpgまたは.pngのみであるため、再度選択して開くことができないことです。

 本来であれば、画像の保存時に、例えば.pngファイルで保存すべきでしょう。

 SaveFileDialogとWriteableBitmapを利用して、.pngファイルとして保存することは可能です。ただし、この処理は、.bmpファイルとして保存するより複雑であったので、本稿ではビットマップ(.bmp)ファイルでの保存としました。

 .pngファイルでの保存方法については、次のブログの記事が参考になりますので、紹介しておきます。

まとめ

 本稿では、サンプルの落書きアプリのコードを解説することで、Silverlight 3の新機能のうち、SaveFileDialogとBitmap APIについて解説しました。

 SaveFileDialogは、Silverlightアプリ上での「ファイルを保存するダイアログ」を提供する機能でした。この機能を利用すると、そのダイアログで指定した保存先にSilverlightアプリからファイルを出力することが可能でした。

 Bitmap APIは、WriteableBitmapクラスとして提供された機能で、Silverlightアプリ上の要素(=UIElement)をビットマップとして取得することができました。

 さて次回は、Silverlightアプリからネットワークの利用可否を確認することができる「ネットワーク監視 API」と、ブラウザなしでSilverlightアプリを実行することができる「ブラウザ外実行(=アウトオブブラウザ体験)」について解説します。お楽しみに!End of Article


 INDEX
  連載:Silverlight 3実践プログラミング 
  SaveFileDialogとBitmap API
    1.SaveFileDialogとBitmap APIを利用したサンプル
  2.サンプル・アプリのソース・コード解説

インデックス・ページヘ  「Silverlight 3実践プログラミング」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)
- PR -

注目のテーマ

業務アプリInsider 記事ランキング

本日 月間
ソリューションFLASH