読者です 読者をやめる 読者になる 読者になる

透過ウィンドウで画像処理する

はじめに

画像処理のプログラムを書くときには、テスト用に画像や動画を使用します。これを準備するのは面倒なので、YouTubeや画像検索の結果画面を処理対象にできたら便利だなと思うことがありました。今回は透過するウィンドウをつくり、その領域で画像処理をしてみます。そうすることでWebカメラでデスクトップを撮影するよりも、きれいに動画像処理が可能となります。

透過ウィンドウの作成

ウィンドウ上の部品を透明にして奥が見えるにして、その部分を画像処理の対象にします。はじめにPanelを貼り付けて適当な色にします。その後、その色を透過として設定することで実現できました。
winforms - C# transparent background for window form - Stack Overflow

public Form1()
{          
  InitializeComponent();

  this.panel1.BackColor = Color.Magenta;
  this.TransparencyKey = Color.Magenta;
}

f:id:wildpie:20150203221241p:plain

それでPanelをキャプチャしたら良いかと思ったんですが、うまくいきませんでした。Magenta一色のbmpが生成されます。

var bitmap = new Bitmap(this.panel1.Width, this.panel1.Height);
this.panel1.DrawToBitmap(bitmap, new Rectangle(0, 0, this.panel1.Width, this.panel1.Height));
bitmap.Save("capture.bmp");

別の方法を調べると、スクリーンキャプチャーをするCopyFromScreenがあったのでこれを使います。
c# - Capture the Screen into a Bitmap - Stack Overflow
同じ場所に結果を表示すると、その結果をキャプチャすることになるので何も変化しなくなりました。思ってたのと違いますが、妥協案で隣に結果表示用のpictureBox2をつけました。Overlapしてる部分の見えないところの画像が撮れると良いんですけどね。
とりあえずYouTubeで動画像処理ができそうです。

f:id:wildpie:20150203231613p:plain

using (var bitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height))
{
  using (var g = Graphics.FromImage(bitmap))
  using (var g2 = pictureBox2.CreateGraphics())
  {
    Point p = PointToScreen(pictureBox1.Location);
    g.CopyFromScreen(p.X, p.Y, 0, 0, pictureBox1.Size, CopyPixelOperation.SourceCopy);

    g2.DrawImage(Binarize(bitmap), 0, 0, bitmap.Width, bitmap.Height);
  }
}