DOBON.NET DOBON.NETプログラミング掲示板過去ログ

DrawStringメソッドで描画した文字列をコピーするには?

環境/言語:[VB.NET .NET Framework3.5]
分類:[.NET]

@ PictureBox1とPictureBox2をフォームに配置する。

A PictureBox1に画像を設定する。
  PictureBox1.Image = Image.FromFile(ファイル名)

B PicutreBox1に文字列を描画する。
  Dim g As Graphics = PictureBox1.CreateGraphics()
g.DrawString(文字列, フォント、ブラシ、レクタングル)
  ※ これで画像に文字列が重なって表示される。

C ボタンクリックイベントでPictureBox1の画像をPictureBox2にコピーする。
  Dim ctl As PictureBox = PictureBox1
Dim img As Bitmap = New Bitmap(ctl.Width, Ctl.Height)
Dim g As Graphics = Graphics.FromImage(img)
Dim dc As IntPtr = g.GetHdc()
PrintWindow(ctl.Handle, dc, 0)
g.ReleaseHdc(dc)
g.Dispose()
PictureBox2.Image = img
※ PictureBox2にはファイルから読み込んだ画像は描画されるが、文字列は描画さない。

PrintWindowは画像をキャプチャーする関数としてDOBON NETで紹介されていたものです。
<System.Runtime.InteropServices.DllImport("User32.dll")> _
Private Shared Function PrintWindow(ByVal hwnd As IntPtr, _
ByVal hDC As IntPtr, ByVal nFlags As Integer) As Boolean
End Function
■No30016に返信(bondaiさんの記事)
>   Dim g As Graphics = PictureBox1.CreateGraphics()
CreateGraphics する際には、Using ブロックを使いましょう。
自分で作成した Graphics は、自分で Dispose しなければなりません。
(Font や Brush も同様に、Dispose が必要なオブジェクトです)


> PictureBox2にはファイルから読み込んだ画像は描画されるが、文字列は描画さない。
(案1) CreateGraphics ではなく、Paint イベントを利用する。
(案2) PictureBox ではなく、元の Image (あるいはそのコピー)に対して描画する。
(案3) キャプチャした画面イメージに、さらに文字列を追加描画する。
魔界の仮面弁士様
ありがとうございます。

その後、ネットで調べると以下の2つの方法でGraphicsクラスのDrawStringメソッドで描画した文字列を含む画像をキャプチャして別のコントロール(PictureBox)に描画できることが分かりました。

1.GraphicsクラスのCopyFromScreenメソッドを使用して画像をキャプチャする。
Dim rc As Rectangle = Me.RectangleToScreen(PictureBox1.Bounds)
Dim img As Bitmap = New Bitmap(rc.Width, rc.Height, PixelFormat.Format32bppArgb)
Using g As Graphics = Graphics.FromImage(img)
g.CopyFromScreen(rc.X, rc.Y, 0, 0, rc.Size, CopyPixelOperation.SourceCopy)
End Using
Using g As Graphics = PictureBox2.CreateGraphics
Dim ctl As PictureBox = PictureBox2
Dim Points As Point() = {New Point(0, 0), New Point(ctl.Width, 0), New Point(0, ctl.Height)}
g.DrawImage(img, Points)
End Using

2.BitBlt APIを使用する。
Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As IntPtr, _
ByVal x As Integer, ByVal y As Integer, ByVal nWidth As Integer, _
ByVal nHeight As Integer, ByVal hSrcDC As IntPtr, ByVal xSrc As Integer, _
ByVal ySrc As Integer, ByVal dwRop As Integer) As Integer

Using g1 As Graphics = PictureBox1.CreateGraphics()
Using g2 As Graphics = PictureBox2.CreateGraphics()
BitBlt(g2.GetHdc.ToInt32, 0, 0, PictureBox2.Width, PictureBox2.Height, g1.GetHdc.ToInt32, 0, 0, &HCC0020)
End Using
End Using
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板