なんとなく

なんとなく書きます

WriteableBitmapの一部を抜き出す方法

/// <summary>
/// 元画像の一部を抜き出した画像の作成
/// </summary>
/// <param name="bitmap">元画像</param>
/// <param name="rectangle">抜き出す領域</param>
/// <returns>抜き出した画像</returns>
static public WriteableBitmap _TrimingImage(WriteableBitmap bitmap , System.Windows.Int32Rect rectangle)
{
   WriteableBitmap miniImage = new WriteableBitmap(rectangle.Width , rectangle.Height , 96 , 96 , System.Windows.Media.PixelFormats.Gray8 , BitmapPalettes.Gray256);
   miniImage.Lock();
   //コピーしたい画像データの一時格納先
   byte[] buffer = new byte[miniImage.PixelWidth * miniImage.PixelHeight];
   //一時格納先にデータの保存
   bitmap.CopyPixels(rectangle , buffer , miniImage.BackBufferStride , 0);
   //保存先にデータの書き込み
   miniImage.WritePixels(new System.Windows.Int32Rect(0 , 0 , miniImage.PixelWidth , miniImage.PixelHeight) , buffer , Convert.ToInt32(miniImage.BackBufferStride) , 0);
   miniImage.Unlock();
   return miniImage;
}

WriteableBitmapに文字を書き込んで画面に表示する方法。

/// <summary>
/// 素の画像に文字を加工して表示する
/// </summary>
/// <param name="bitmap">素の画像</param>
/// <param name="image">Imageコントロール</param>
/// <param name="Message">表示したい文字</param>
public void MyDrawBitmap(WriteableBitmap bitmap , Image image,string Message="message:nothing")
{
   DrawingGroup drawingGroup = new DrawingGroup();
   using (var drawContent = drawingGroup.Open())
   {
      //素の画像を先におく
      drawContent.DrawImage(bitmap , new System.Windows.Rect(0 , 0 , bitmap.PixelWidth , bitmap.PixelHeight));
      //書きたい文字をおく。フォントは"Verdana"の文字を変えれば変更可能
      drawContent.DrawText(new FormattedText(Message , System.Globalization.CultureInfo.CurrentUICulture , System.Windows.FlowDirection.LeftToRight , new Typeface("Verdana") , 100 , Brushes.Gold) , new System.Windows.Point(100 , 100));
   }
   image.Source = new DrawingImage(drawingGroup);
}

画像とかが別のスレッドに所有権うんぬんで触れないときの対処。

BackgroundWorkerやThreadで画像を作って
表示しようとした時に別スレッドが所有権を持っているからでエラーが出るとき。

表示しようとしている画像にFreezeメソッドを使えばいい。

WriteableBitmap writeableBitmap;
//色々処理する。

//Freezeすると表示させようとしても怒られなくなるはず
writeableBitmap.Freeze()


ついでに忘れないように
WriteableBitmapよりBitmapImageの方が読み込みが早い

System.Windows.Controls.Imageの保存方法

元の画像に線や文字などの描画を追加して元の画像サイズで保存する方法。
もっと効率のいい方法があるかもしれないがわからん。

SaveImage関数は下記で書いたやつ。
引数のみを変更したやつ
WriteableBitmapからRenderTargetBitmapに
http://d.hatena.ne.jp/stardust444/20130223/1361613956

/// <summary>
/// 加工されたImageコントロールを元の画像サイズで保存
/// </summary>
/// <param name="fileName">保存するファイル名</param>
/// <param name="image">画像と追加描画されたImageコントロール</param>
/// <param name="rawImageSize">元の画像サイズ</param>
public void Save(string fileName , Image image,Size rawImageSize)
{
   //画像の素を作る。
   var img = new RenderTargetBitmap(Convert.ToInt32(rawImageSize.Width) , Convert.ToInt32(rawImageSize.Height) , 96 , 96 , PixelFormats.Pbgra32);
   //img.Render用にVisualを作成
   var drawingVisual = new DrawingVisual();
   //操作用にDrawContextの作成 
   var drawContext = drawingVisual.RenderOpen();
   //描画データを画像に入れる
   drawContext.DrawImage(image.Source , new Rect(0 , 0 , Convert.ToInt32(rawImageSize.Width), Convert.ToInt32(rawImageSize.Height)));
   //DrawContextに描画データの書き込み
   drawContext.Close();
   //RenderTargetBitmapに書き込み。
   img.Render(drawingVisual);
   //画像の保存
   //この関数は前に書いた関数の引数をWriteableBitmapをRenderTargetBitmapに変えたやつ
   SaveImage(img , fileName);
}