InkCnavasに描いた絵を画像として保存するTipsを紹介します。
下の方にコードを示しますので、併せてご覧ください。
1) InkCanvasに描かれた画像を別な場所に転送(描画)します。
この転送先は、DrawingVisual クラスを使用して作成した変数とします。
2) 作成した変数(DrawingVisual オブジェクト)の RederOpen() メソッドを使用し、返されたDrawingContext オブジェクトに対して描画行います。
3) 2)で描画されたオブジェクトを RendarTagetBitmap クラスを利用して、ビットマップへ変換しておきます。
4) ビットマップへ変換されたオブジェクトから、目的の形式あわせたエンコーダーのインスタンスを作成します。
使用できるエンコーダーには下記のようなものがあります。
イメージ用エンコーダークラス
クラス名 | 説明 |
---|---|
BmpBitmapEncoder | BMP形式のエンコーダー |
GifBitmapEncoder | GIF形式のエンコーダー |
JpegBitmapEncoder | JPEG形式のエンコーダー |
PngBitmapEncoder | PNG形式のエンコーダー |
TiffBitmapEncoder | TIFF形式のエンコーダー |
5) BitmapFrameクラスからビットマップフレームを作成して、4)で作成したエンコーダーのフレームに追加します。
6) 最後に Streamクラスを使用して、画像をファイルに書き込みます。
下記がキャンバスに描いた絵を画像ファイルとして保存する例です。
XAMLの例
<StackPanel Name="parentStack"> <StackPanel Orientation="Horizontal" Name="menuStack"> <Button Name="btnSave" Content="保存" /> </StackPanel> <InkCanvas Name="InkCanvas1" EditingMode="Ink" /> </StackPanel>
VBの例
' [保存]ボタンクリック時の処理 Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnSave.Click Dim dlgSave As New Microsoft.Win32.SaveFileDialog() dlgSave.Filter = "ビットマップファイル(*.bmp)|*.bmp|" & "JPEGファイル(*.jpg)|*,jpg|" & "PNGファイル(*.png)|*.png" dlgSave.AddExtension = True If dlgSave.ShowDialog() Then '拡張子を取得する Dim extension As String = System.IO.Path.GetExtension(dlgSave.FileName).ToUpper() 'ストロークが描画されている境界を取得 Dim rectBounds As Rect = InkCanvas1.Strokes.GetBounds() '描画先を作成 Dim dv As New DrawingVisual Dim dc As DrawingContext = dv.RenderOpen() '描画エリアの位置補正(補正しないと黒い部分ができてしまう) dc.PushTransform(New TranslateTransform(-rectBounds.X, -rectBounds.Y)) '描画エリア(dc)に四角形を作成 '四角形の大きさはストロークが描画されている枠サイズとし、 '背景色はInkCanvasコントロールと同じにする dc.DrawRectangle(InkCanvas1.Background, Nothing, rectBounds) '上記で作成した描画エリアに(dc)にInkCanvasのストロークを描画 InkCanvas1.Strokes.Draw(dc) dc.Close() 'ビジュアルオブジェクトをビットマップに変換する Dim rtb As New RenderTargetBitmap( rectBounds.Width, rectBounds.Height, 96, 96, PixelFormats.Default) rtb.Render(dv) 'ビットマップエンコーダー変数の宣言 Dim enc As BitmapEncoder = Nothing '画像のエンコーダーを作成(拡張子で判断) Select Case extension Case ".BMP" enc = New BmpBitmapEncoder() Case ".JPG" enc = New JpegBitmapEncoder() Case ".PNG" enc = New PngBitmapEncoder() End Select If Not IsNothing(enc) Then 'ビットマップフレームを作成してエンコーダーにフレームを追加する enc.Frames.Add(BitmapFrame.Create(rtb)) 'ファイルに書き込む Dim stream As System.IO.Stream = System.IO.File.Create(dlgSave.FileName) enc.Save(stream) stream.Close() End If End If End Sub
C#の例
// [保存]ボタンクリック時の処理 private void btnSave_Click(object sender, RoutedEventArgs e) { Microsoft.Win32.SaveFileDialog dlgSave = new Microsoft.Win32.SaveFileDialog(); dlgSave.Filter = "ビットマップファイル(*.bmp)|*.bmp|" + "JPEGファイル(*.jpg)|*,jpg|" + "PNGファイル(*.png)|*.png"; dlgSave.AddExtension = true; if ((bool)dlgSave.ShowDialog()) { // 拡張子を取得する string extension = System.IO.Path.GetExtension(dlgSave.FileName).ToUpper(); // ストロークが描画されている境界を取得 Rect rectBounds = inkCanvas1.Strokes.GetBounds(); // 描画先を作成 DrawingVisual dv = new DrawingVisual(); DrawingContext dc = dv.RenderOpen(); // 描画エリアの位置補正(補正しないと黒い部分ができてしまう) dc.PushTransform(new TranslateTransform(-rectBounds.X, -rectBounds.Y)); // 描画エリア(dc)に四角形を作成 // 四角形の大きさはストロークが描画されている枠サイズとし、 // 背景色はInkCanvasコントロールと同じにする dc.DrawRectangle(inkCanvas1.Background, null, rectBounds); // 上記で作成した描画エリア(dc)にInkCanvasのストロークを描画 inkCanvas1.Strokes.Draw(dc); dc.Close(); // ビジュアルオブジェクトをビットマップに変換する RenderTargetBitmap rtb = new RenderTargetBitmap( (int)rectBounds.Width, (int)rectBounds.Height, 96,96, PixelFormats.Default); rtb.Render(dv); // ビットマップエンコーダー変数の宣言 BitmapEncoder enc = null; switch (extension) { case ".BMP": enc = new BmpBitmapEncoder(); break; case ".JPG": enc = new JpegBitmapEncoder(); break; case ".PNG": enc = new PngBitmapEncoder(); break; } if (enc != null) { // ビットマップフレームを作成してエンコーダーにフレームを追加する enc.Frames.Add(BitmapFrame.Create(rtb)); // ファイルに書き込む System.IO.Stream stream = System.IO.File.Create(dlgSave.FileName); enc.Save(stream); stream.Close(); } } }