StretchBlt について への返答
投稿で使用できる特殊コードの説明。(別タブで開きます。)
以下の返答は逆順(新しい順)に並んでいます。
投稿者 (削除されました)  ()
投稿日時
2010/2/11 05:18:12
(削除されました)
投稿者 (削除されました)  ()
投稿日時
2010/2/11 05:16:10
(削除されました)
投稿者 (削除されました)  ()
投稿日時
2010/2/10 07:35:00
(削除されました)
投稿者 反る戸  (社会人)
投稿日時
2010/2/10 07:31:33
自己解決しました。以下のURLに答えがありました。
http://dobon.net/vb/bbs/log3-39/24003.html#ID24003
こういうことだったようです。
1.GraphicsはImageから取得してよいが、転送元のデバイスコンテキストは
BitmapからGetHbitmap()で作成したbmpのハンドルをSelectObjectで選択して
やらなければならない。
2.転送先のデバイスコンテキストでSelectObjectを使ってはいけない。
質問時のコードのButton1_Clickを以下のように修正するとうまくいきました。
SelectObject()とDeleteObject()の宣言は別に追加していますが。
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim g1 As Graphics = Graphics.FromImage(PictureBox1.Image)
Dim g2 As Graphics = Graphics.FromImage(PictureBox2.Image)
g2.DrawRectangle(Pens.BlueViolet, 2, 2, 26, 26)
Dim srcDc As IntPtr = g1.GetHdc()
Dim destDc As IntPtr = g2.GetHdc()
Dim srcHbmp As IntPtr = DirectCast(Me.PictureBox1.Image, Bitmap).GetHbitmap()
SelectObject(srcDc, srcHbmp)
Dim retval As Integer
retval = StretchBlt(destdc, 0, 0, 32, 32, srcdc, x, y, 16, 16, SRCCOPY)
DeleteObject(srcHbmp)
g2.ReleaseHdc(destdc)
g1.ReleaseHdc(srcdc)
g2.Dispose()
g1.Dispose()
Refresh()
x += 16
If x > 320 Then
x = 0
y += 16
End If
End Sub
お騒がせしました。今後ともよろしくお願いします。
http://dobon.net/vb/bbs/log3-39/24003.html#ID24003
こういうことだったようです。
1.GraphicsはImageから取得してよいが、転送元のデバイスコンテキストは
BitmapからGetHbitmap()で作成したbmpのハンドルをSelectObjectで選択して
やらなければならない。
2.転送先のデバイスコンテキストでSelectObjectを使ってはいけない。
質問時のコードのButton1_Clickを以下のように修正するとうまくいきました。
SelectObject()とDeleteObject()の宣言は別に追加していますが。
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim g1 As Graphics = Graphics.FromImage(PictureBox1.Image)
Dim g2 As Graphics = Graphics.FromImage(PictureBox2.Image)
g2.DrawRectangle(Pens.BlueViolet, 2, 2, 26, 26)
Dim srcDc As IntPtr = g1.GetHdc()
Dim destDc As IntPtr = g2.GetHdc()
Dim srcHbmp As IntPtr = DirectCast(Me.PictureBox1.Image, Bitmap).GetHbitmap()
SelectObject(srcDc, srcHbmp)
Dim retval As Integer
retval = StretchBlt(destdc, 0, 0, 32, 32, srcdc, x, y, 16, 16, SRCCOPY)
DeleteObject(srcHbmp)
g2.ReleaseHdc(destdc)
g1.ReleaseHdc(srcdc)
g2.Dispose()
g1.Dispose()
Refresh()
x += 16
If x > 320 Then
x = 0
y += 16
End If
End Sub
お騒がせしました。今後ともよろしくお願いします。
投稿者 (削除されました)  ()
投稿日時
2010/2/10 04:04:27
(削除されました)
投稿者 反る戸  (社会人)
投稿日時
2010/2/10 03:53:26
直前の削除は私です。申し訳ありません。
cupidさん、レスありがとうございます。
>それに普通、ドットネットでグラフィックを扱う場合、
>「デバイスコンテキスト」を考える必要ないと思うけど。
おっしゃることはごもっともなのですが、敢えてWindowsのAPIを使うとすれば、
ということでご助言いただけるとありがたいです。
cupidさん、レスありがとうございます。
>それに普通、ドットネットでグラフィックを扱う場合、
>「デバイスコンテキスト」を考える必要ないと思うけど。
おっしゃることはごもっともなのですが、敢えてWindowsのAPIを使うとすれば、
ということでご助言いただけるとありがたいです。
投稿者 (削除されました)  ()
投稿日時
2010/2/10 03:50:13
(削除されました)
投稿者 cupid  (社会人)
投稿日時
2010/2/9 19:55:27
「StretchBlt」って固有名詞じゃないのかな?
それに普通、ドットネットでグラフィックを扱う場合、
「デバイスコンテキスト」を考える必要ないと思うけど。
それに普通、ドットネットでグラフィックを扱う場合、
「デバイスコンテキスト」を考える必要ないと思うけど。
投稿者 (削除されました)  ()
投稿日時
2010/2/9 04:27:23
(削除されました)
投稿者 反る戸  (社会人)
投稿日時
2010/2/9 03:38:19
あにすさんレスありがとうございます。
>いまいちやりたいことが見えないのですが、
質問の仕方が悪く、申し訳ございません。
やりたいことは、
PictureBox1.ImageからPictureBox2.ImageへのStretchBltを使用した
拡大転送です。
最初はDrawImageでやっていたのですが、思うような拡大が出来ません
でした。これに関しても色々試行錯誤はしておりまして、お聞きしたい
ことは有るのですが、このスレッドではStretchBltに限定してご助言を
頂戴したいと思っております。。恐縮ですが、DrawImageについては、別
のスレッドで新たに質問させて 下さい。
>いまいちやりたいことが見えないのですが、
質問の仕方が悪く、申し訳ございません。
やりたいことは、
PictureBox1.ImageからPictureBox2.ImageへのStretchBltを使用した
拡大転送です。
最初はDrawImageでやっていたのですが、思うような拡大が出来ません
でした。これに関しても色々試行錯誤はしておりまして、お聞きしたい
ことは有るのですが、このスレッドではStretchBltに限定してご助言を
頂戴したいと思っております。。恐縮ですが、DrawImageについては、別
のスレッドで新たに質問させて 下さい。
投稿者 あにす  (社会人)
投稿日時
2010/2/8 08:35:38
いまいちやりたいことが見えないのですが、こういうことでしょうか?
これでよければ、StretchBlt関数は使わなくて済みます。
Public Class Form1
Private Sub Form1_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Me.Load
Me.PictureBox1.Image = Image.FromFile("..\..\..\chipset13.png")
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
Dim img As New Bitmap(32, 32)
Using g As Graphics = Graphics.FromImage(img)
g.DrawImage(Me.PictureBox1.Image, New Rectangle(0, 0, 32, 32), _
New Rectangle(0, 0, 16, 16), GraphicsUnit.Pixel)
End Using
Me.PictureBox2.Image = img
End Sub
End Class
これでよければ、StretchBlt関数は使わなくて済みます。
投稿者 (削除されました)  ()
投稿日時
2010/2/8 00:16:52
(削除されました)
投稿者 (削除されました)  ()
投稿日時
2010/2/7 23:33:46
(削除されました)
投稿者 (削除されました)  ()
投稿日時
2010/2/7 20:57:13
(削除されました)
投稿者 (削除されました)  ()
投稿日時
2010/2/7 20:52:31
(削除されました)
投稿者 (削除されました)  ()
投稿日時
2010/2/7 17:56:12
(削除されました)
投稿者 反る戸  (社会人)
投稿日時
2010/2/7 00:32:57
はじめまして
VB2005のProfessional Edition を使用しています。VB2005でStretchBltを
使用したいと思い、ネットで検索した所下記のページを見つけました。
http://standardization.at.webry.info/200810/article_2.html
このページのソースを参考に以下のようなプログラムを作成してみました。
フォームにピクチャーボックス2つとボタン1つを貼っています。
このコードでは、ピクチャーボックスからデバイスコンテキストを取得して
いますが、それですとスクリーンのデバイスコンテキストになっているようで、
PictutureBox1の上にPictureBox2が重なる部分ではPictureBox2の背景が転送さ
れ、更にはフォームをはみ出てデスクトップや別のアプリのウィンドウの一部
が画像として転送されてしまいます。
試しに、ピクチャーボックスのImageからGraphicsを作成してみました
が、それだと真っ黒な四角が描画されます。
メモリデバイスコンテキストを作らなければ駄目なのかと思い、srcdcの
生成を以下のようにしてみました。
Dim srcdc As IntPtr = CreateCompatibleDC(destdc)
Dim hbmSrc As IntPtr = DirectCast(Me.PictureBox1.Image, _
Bitmap).GetHbitmap()
SelectObject(srcdc, hbmSrc)
ソース側はこれでうまくいき、PictureBox1のImageの内容を転送できる
ようになりました。
しかし、デスティネーション側はピクチャーボックスのGraphicsを使用
しないとうまくいきません。Imageをデスティネーションにする方法はない
のでしょうか?
VB2005のProfessional Edition を使用しています。VB2005でStretchBltを
使用したいと思い、ネットで検索した所下記のページを見つけました。
http://standardization.at.webry.info/200810/article_2.html
このページのソースを参考に以下のようなプログラムを作成してみました。
フォームにピクチャーボックス2つとボタン1つを貼っています。
このコードでは、ピクチャーボックスからデバイスコンテキストを取得して
いますが、それですとスクリーンのデバイスコンテキストになっているようで、
PictutureBox1の上にPictureBox2が重なる部分ではPictureBox2の背景が転送さ
れ、更にはフォームをはみ出てデスクトップや別のアプリのウィンドウの一部
が画像として転送されてしまいます。
Public Class Form1
Private Declare Function StretchBlt Lib "gdi32" Alias "StretchBlt" _
(ByVal hdc As Integer, ByVal x As Integer, ByVal y As Integer, _
ByVal nWidth As Integer, ByVal nHeight As Integer, _
ByVal hSrcDC As Integer, _
ByVal xSrc As Integer, ByVal ySrc As Integer, _
ByVal nSrcWidth As Integer, ByVal nSrcHeight As Integer, _
ByVal dwRop As Integer) As Integer
Private Const SRCCOPY = &HCC0020 ' (DWORD) dest = source
Private x As Integer
Private y As Integer
Private Sub Form1_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Me.Load
Dim gr1 As Graphics
Dim gr2 As Graphics
Me.PictureBox1.Image = New Bitmap(480, 256)
Me.PictureBox1.Width = Me.PictureBox1.Image.Width
Me.PictureBox1.Height = Me.PictureBox1.Image.Height
gr1 = Graphics.FromImage(Me.PictureBox1.Image)
gr1.DrawImage(Image.FromFile("..\..\..\chipset13.png"), 0, 0)
gr1.Dispose()
Me.PictureBox2.Image = New Bitmap(32, 32)
x = 0
y = 0
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
Dim g1 As Graphics = PictureBox1.CreateGraphics()
Dim g2 As Graphics = PictureBox2.CreateGraphics()
Dim srcdc As IntPtr = g1.GetHdc()
Dim destdc As IntPtr = g2.GetHdc()
Dim retval As Integer
retval = StretchBlt(destdc, 0, 0, 32, 32, _
srcdc, x, y, 16, 16, SRCCOPY)
g2.ReleaseHdc(destdc)
g1.ReleaseHdc(srcdc)
g2.Dispose()
g1.Dispose()
x += 16
If x > 320 Then
x = 0
y += 16
End If
End Sub
End Class
試しに、ピクチャーボックスのImageからGraphicsを作成してみました
が、それだと真っ黒な四角が描画されます。
メモリデバイスコンテキストを作らなければ駄目なのかと思い、srcdcの
生成を以下のようにしてみました。
Dim srcdc As IntPtr = CreateCompatibleDC(destdc)
Dim hbmSrc As IntPtr = DirectCast(Me.PictureBox1.Image, _
Bitmap).GetHbitmap()
SelectObject(srcdc, hbmSrc)
ソース側はこれでうまくいき、PictureBox1のImageの内容を転送できる
ようになりました。
しかし、デスティネーション側はピクチャーボックスのGraphicsを使用
しないとうまくいきません。Imageをデスティネーションにする方法はない
のでしょうか?