[リストへもどる]
一括表示

投稿時間:2003/07/20(Sun) 13:34
投稿者名:おじん
URL :
タイトル:
BitBltの使い方
BitBlt pic1,x1,y1,pic2,x2,y2,srcで、x1,y1,x2,y2はLongで
正数です。そこで、pic1のマイナス座標にcopyしたいときには
どのようにしたらよいのでしょうか?
(pic2を少しだけ左にずらしてpic1にコピーしたい。上についても
同様です)

投稿時間:2003/07/20(Sun) 16:39
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re: BitBltの使い方
> BitBlt pic1,x1,y1,pic2,x2,y2,srcで、x1,y1,x2,y2はLongで
> 正数です。そこで、pic1のマイナス座標にcopyしたいときには
> どのようにしたらよいのでしょうか?
> (pic2を少しだけ左にずらしてpic1にコピーしたい。上についても
> 同様です)

こう言う事でしょうか?
Option Explicit
Private Declare Function BitBlt Lib "GDI32" _
    (ByVal hDCDest As Long, ByVal XDest As Long, _
     ByVal YDest As Long, ByVal nWidth As Long, _
     ByVal nHeight As Long, ByVal hDCSrc As Long, _
     ByVal XSrc As Long, ByVal YSrc As Long, ByVal dwRop As Long) As Long
Private Const SRCCOPY = &HCC0020
Private Sub Command1_Click()
    BitBlt Picture1.hDC, -5&, -5&, Picture2.ScaleWidth, Picture2.ScaleHeight, Picture2.hDC, 0&, 0&, SRCCOPY
    Picture1.Refresh
End Sub

投稿時間:2003/07/20(Sun) 18:33
投稿者名:おじん
URL :
タイトル:
Re^2: BitBltの使い方
> > BitBlt pic1,x1,y1,pic2,x2,y2,srcで、x1,y1,x2,y2はLongで
> > 正数です。そこで、pic1のマイナス座標にcopyしたいときには
> > どのようにしたらよいのでしょうか?
> > (pic2を少しだけ左にずらしてpic1にコピーしたい。上についても
> > 同様です)
>
> こう言う事でしょうか?
> Option Explicit
> Private Declare Function BitBlt Lib "GDI32" _
>     (ByVal hDCDest As Long, ByVal XDest As Long, _
>      ByVal YDest As Long, ByVal nWidth As Long, _
>      ByVal nHeight As Long, ByVal hDCSrc As Long, _
>      ByVal XSrc As Long, ByVal YSrc As Long, ByVal dwRop As Long) As Long
> Private Const SRCCOPY = &HCC0020
> Private Sub Command1_Click()
>     BitBlt Picture1.hDC, -5&, -5&, Picture2.ScaleWidth, Picture2.ScaleHeight, Picture2.hDC, 0&, 0&, SRCCOPY
>     Picture1.Refresh
> End Sub
早速ありがとうございます。
この、「−5&」が思うとおり(=左にずれない)にならないのです。
みかけ、「+5&」でもないようなのです(+方向と思いますが)。
なにか、どこかを調べればよいのでしょうか。

投稿時間:2003/07/20(Sun) 19:08
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re^3: BitBltの使い方
> > Private Declare Function BitBlt Lib "GDI32" _
> >     (ByVal hDCDest As Long, ByVal XDest As Long, _
> >      ByVal YDest As Long, ByVal nWidth As Long, _
> >      ByVal nHeight As Long, ByVal hDCSrc As Long, _
> >      ByVal XSrc As Long, ByVal YSrc As Long, ByVal dwRop As Long) As Long
> > Private Const SRCCOPY = &HCC0020
> > Private Sub Command1_Click()
> >     BitBlt Picture1.hDC, -5&, -5&, Picture2.ScaleWidth, Picture2.ScaleHeight, Picture2.hDC, 0&, 0&, SRCCOPY
> >     Picture1.Refresh
> > End Sub
> 早速ありがとうございます。
> この、「−5&」が思うとおり(=左にずれない)にならないのです。
> みかけ、「+5&」でもないようなのです(+方向と思いますが)。
> なにか、どこかを調べればよいのでしょうか。
Picture2に表示されている画像を上方向と左方向にずらしてPicture1に表示したいと
言う事ではないのですか?
ずらして表示するという事は、元々 XY座標が 0,0 の位置に表示されているのですから
-5,-5 にすれば上方向に5ピクセル、左方向に5ピクセルずれて(その分表示されない)
表示されます。
Pictureコントロールのプロパティを何も設定しないで下記を先ほどのコードに追加して下さい。
-5,-5 で効果が解りづらいなら -10,-10に変更して見て下さい。

Private Sub Form_Load()
    Picture1.Move 500, 500, 3000, 3000
    Picture1.AutoRedraw = True
    Picture2.Move 4000, 500, 3000, 3000
    Picture2.AutoRedraw = True
    Picture2.Picture = LoadPicture("c:\test.bmp")
End Sub

投稿時間:2003/07/20(Sun) 19:37
投稿者名:おじん
URL :
タイトル:
Re^4: BitBltの使い方
> > > Private Declare Function BitBlt Lib "GDI32" _
> > >     (ByVal hDCDest As Long, ByVal XDest As Long, _
> > >      ByVal YDest As Long, ByVal nWidth As Long, _
> > >      ByVal nHeight As Long, ByVal hDCSrc As Long, _
> > >      ByVal XSrc As Long, ByVal YSrc As Long, ByVal dwRop As Long) As Long
> > > Private Const SRCCOPY = &HCC0020
> > > Private Sub Command1_Click()
> > >     BitBlt Picture1.hDC, -5&, -5&, Picture2.ScaleWidth, Picture2.ScaleHeight, Picture2.hDC, 0&, 0&, SRCCOPY
> > >     Picture1.Refresh
> > > End Sub
> > 早速ありがとうございます。
> > この、「−5&」が思うとおり(=左にずれない)にならないのです。
> > みかけ、「+5&」でもないようなのです(+方向と思いますが)。
> > なにか、どこかを調べればよいのでしょうか。
> Picture2に表示されている画像を上方向と左方向にずらしてPicture1に表示したいと
> 言う事ではないのですか?
> ずらして表示するという事は、元々 XY座標が 0,0 の位置に表示されているのですから
> -5,-5 にすれば上方向に5ピクセル、左方向に5ピクセルずれて(その分表示されない)
> 表示されます。
> Pictureコントロールのプロパティを何も設定しないで下記を先ほどのコードに追加して下さい。
> -5,-5 で効果が解りづらいなら -10,-10に変更して見て下さい。
>
> Private Sub Form_Load()
>     Picture1.Move 500, 500, 3000, 3000
>     Picture1.AutoRedraw = True
>     Picture2.Move 4000, 500, 3000, 3000
>     Picture2.AutoRedraw = True
>     Picture2.Picture = LoadPicture("c:\test.bmp")
> End Sub
ありがとうございました。
「元画像」を動かすことに気が付きませんでした。というのは、
for n=0 to 2  '2=2,3......n
  bitblt pic1,n*pic2width,0,pic2width,pic2height,0,0,vbsrccopy
next n
ということをやりたかったとき、n=0の場合、画像を気持ち的に
左にしたかったのです(タイル敷き、万華鏡風)。

投稿時間:2003/07/20(Sun) 20:00
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re^5: BitBltの使い方
全体のコードを投稿して頂ければ、もう少し理解できたのですが。
BitBlt APIの使用方法については下記を見て下さい。
http://www.microsoft.com/japan/developer/library/jpgdipf/_win32_bitblt.htm


> 左にしたかったのです(タイル敷き、万華鏡風)。

デスクトップの壁紙のように表示したいなら
CreatePatternBrush SelectObject PatBlt DeleteObject 等のAPIを使用
した方が簡単かと思います。

投稿時間:2003/07/21(Mon) 05:17
投稿者名:おじん
URL :
タイトル:
Re^6: BitBltの使い方
ありがとうございました。長くなりますが、作成中のソースを添付します。

FormにPicture1:256 x 256 Pixels 元画像を配置
      Picture2:256 x 256 Pixels コピー先
      Picture3: 64 x  64 Pixels 切り取った画像
      Picture4: 64 x  64 Pixels 作業用
   いずれも、scalemode=vbPixels
                autoredraw=true

'------------------------------------------------
'      万華鏡もどき     KaleidoScope
'------------------------------------------------
Option Explicit
'------------------------------------------------
Declare Function BitBlt Lib "gdi32" ( _
        ByVal hDestDC As Long, _
        ByVal X As Long, _
        ByVal Y As Long, _
        ByVal nWidth As Long, _
        ByVal nHeight As Long, _
        ByVal hSrcDC As Long, _
        ByVal xSrc As Long, _
        ByVal ySrc As Long, _
        ByVal dwRop As Long) As Long
        
    Const SRCERASE = &H440328
    Const SRCINVERT = &H660046

    Dim x0!, y0!
    Dim w&, h&       'Picture3の高さ・幅

Private Sub Form_Load()
    w = Picture3.ScaleWidth
    h = Picture3.ScaleHeight
End Sub

'------------------------------------------------
Private Sub Picture1_MouseDown( _
        Button As Integer, Shift As Integer, _
        X As Single, Y As Single)
'または
'Private Sub Picture1_MouseMove( _
'        Button As Integer, Shift As Integer, _
'        X As Single, Y As Single)
    'Picture1のカーソルの周りを切り取りPicture3に貼り付ける
    x0 = X - 16: y0 = Y - 16 'カーソルの初期値 -16は少しずらすための調整
    Call Draw3_sub           '正三角形→正六角形
'    Call Draw4_sub          '正四角形(ソースは割愛)
    
End Sub

Private Sub Draw3_sub()
    Dim n!, m!, c&, a, x1!, y1!, x2!, y2!
    a = 1.732 ' 対称軸 y=ax andor y=-ax の係数

    picture1.Scale (0, 256)-(256, 0)
    picture2.Scale (-256, 256)-(256, -256) '意味ないかも?
    picture3.Scale (-32, 32)-(32, -32)   'Picture1を切り取った位置と
'   正三角形の左半分             表示相対位置が反転しているようだ
    For n = 0 To 16 Step 0.5                  
        For m = 0 To 1.732 * n
            c = picture1.Point(x0 + n, y0 + m)
            picture3.PSet (n, m), c           'カーソルの位置
            x1 = (-2 * n + 3.464 * m) / 4
            y1 = (3.464 * n + 2 * m) / 4
            picture3.PSet (x1, y1), c         'y=axに対象
            x2 = (-2 * x1 - 3.464 * y1) / 4
            y2 = (-3.464 * x1 + 2 * y1) / 4
            picture3.PSet (x2, y2), c         'y=-axに対象
            picture3.PSet (x2, -y2), c        'y軸に対象
            x1 = (-2 * x2 - 3.464 * y2) / 4
            y1 = (3.464 * x2 - 2 * y2) / 4
            picture3.PSet (x1, y1), c         'y=-axに対象
            picture3.PSet (n, -m), c          'x軸に対象
        Next m
    Next n
'   正三角形の右半分
    For n = 16 To 32 Step 0.5
        For m = 0 To 1.732 * (32 - n)
            c = picture1.Point(x0 + n, y0 + m)
            picture3.PSet (n, m), c           'カーソルの位置
            x1 = (-2 * n + 3.464 * m) / 4
            y1 = (3.464 * n + 2 * m) / 4
            picture3.PSet (x1, y1), c         'y=axに対象
            x2 = (-2 * x1 - 3.464 * y1) / 4
            y2 = (-3.464 * x1 + 2 * y1) / 4
            picture3.PSet (x2, y2), c         'y=-axに対象
            picture3.PSet (x2, -y2), c        'X軸に対象
            x1 = (-2 * x2 - 3.464 * y2) / 4
            y1 = (3.464 * x2 - 2 * y2) / 4
            picture3.PSet (x1, y1), c         'y=-axに対象
            picture3.PSet (n, -m), c          'x軸に対象
        Next m
    Next n
'上で切り取った正六角形をタイル敷きする
'           +-の数値はきれいにしくための調整数(試行錯誤)
'           もっときれいに並べる方法=関係式があるような!!
  picture2.Cls
'
'今回の質問は以下の部分が上手くいかないためです
'解決法としては、SplitDrawのBitBlt部分を修正する必要があるようです
'
    For n = 0 To 3
'   最初の部分はPicture2より左に少しはみだして貼り付けたい
        SplitDraw picture2, picture3, picture4, 0, n * h * 0.85 - 8
        SplitDraw picture2, picture3, picture4, w + 28, n * h * 0.85 - 8
'       SplitDraw picture2, picture3, picture4, 3 * w + 28, n * h * 0.85 - 8
'   正六角形を少しだけ下にずらして貼り付ける
        SplitDraw picture2, picture3, picture4, 46, n * h * 0.85 - 8 - 8
        SplitDraw picture2, picture3, picture4, 2 * w + 28, n * h * 0.85 - 8
    Next n
    
'picture2.Refresh

End Sub
'------------------------------------------------
'      透過画像を合成描画  
'------------------------------------------------
Private Sub SplitDraw( _
        pic1 As Object, pic2 As Object, pic3 As Object, _
        X As Long, Y As Long)
    Dim i As Long
    Dim j As Long
    Dim lngRet As Long
    
    Dim a1 As Long, a2 As Long, a3 As Long
    Dim p1 As Long, p2 As Long, p3 As Long
    
    For i = 0 To pic2.ScaleWidth - 1
        For j = 0 To pic2.ScaleHeight - 1
            'マスク色(白色)部分以外を描画
            If pic2.Point(i, j) <> vbWhite Then
                pic3.PSet (i, j), vbBlack
            End If
        Next
    Next
'
'場合によって、pic3の0,0を+数値(ずらせたい値)に変える
'              Width,Heightも要変更
    lngRet = BitBlt(pic1.hDC, X, Y, _
                    pic3.ScaleWidth, pic3.ScaleHeight, _
                    pic3.hDC, 0, 0, SRCERASE)
    lngRet = BitBlt(pic1.hDC, X, Y, _
                    pic2.ScaleWidth, pic2.ScaleHeight, _
                    pic2.hDC, 0, 0, SRCINVERT)
    '画面に表示
    pic1.Refresh
    
End Sub
'------------------------------------------------

投稿時間:2003/07/21(Mon) 09:56
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re^7: BitBltの使い方
下記の3箇所を変更して見てはどうでしょうか?


For n = 0 To 16 Step 0.1    'できるだけ小さい数字にした方が綺麗に

' 正三角形の右半分
For n = 16 To 32 Step 0.1       'できるだけ小さい数字にした方が綺麗に
0.01 位にすると上下方向のどっと抜けが改善されるのですが遅くなるので
別途、別途どっと抜けの工夫をすればいいかも



For n = 0 To 3
'   最初の部分はPicture2より左に少しはみだして貼り付けたい
    SplitDraw Picture2, Picture3, Picture4, -1, n * 57 - 5 ' - 8 - (n * 8)
    SplitDraw Picture2, Picture3, Picture4, 62, n * 57 - 5 '- 8 - (n * 8)
    SplitDraw Picture2, Picture3, Picture4, 125, n * 57 - 5 '- 8 - (n * 8)
    SplitDraw Picture2, Picture3, Picture4, 188, n * 57 - 5 '- 8 - (n * 8)
Next n


    lngRet = BitBlt(pic1.hDC, X, Y, _
                    pic3.ScaleWidth, pic3.ScaleHeight, _
                    pic3.hDC, 0, 0, SRCERASE)
    lngRet = BitBlt(pic1.hDC, X, Y, _
                    pic2.ScaleWidth, -pic2.ScaleHeight, _
                    pic2.hDC, 0, 0, SRCINVERT)

バックカラーは白で統一した方が綺麗に表示されるようです。

投稿時間:2003/07/21(Mon) 13:50
投稿者名:おじん
URL :
タイトル:
Re^8: BitBltの使い方
私の知識では、ドット抜けのこと、速さとどちらを優先選択するかということです。
敷き詰めの部分、意図することが伝わらなかったようです。正六面体を”隙間なく”
敷き詰めたかったのです。
> For n = 0 To 3
> '   最初の部分はPicture2より左に少しはみだして貼り付けたい
>     SplitDraw Picture2, Picture3, Picture4, -1, n * 57 - 5 ' - 8 - (n * 8)
> Next n
の部分を次のようにして完成しました。SplitDraw関数もパラメータを2つ追加しました。
(数値は、試行錯誤の末です。論理的にしたいのですが!!!)
    For n = 0 To 3
    '1列目。六角形の左端を切り取り貼り付ける
        SplitDraw pic2, pic3, pic4, -1, n * 57 - 5, 16, 0
                                                    ^^^^^^
    Next n
    '2列目。上半分を切り取る
    SplitDraw pic2, pic3, pic4, 31, 0, 0, 32
                                      ^^^^^^^
    For n = 1 To 3
    '2列目。六角形全体
        SplitDraw pic2, pic3, pic4, 31, n * 57 - 5 - 28
    Next n
    For n = 0 To 3
    '3列目。六角形全体
        SplitDraw pic2, pic3, pic4, 79, n * 57 - 5
    Next n
    '4列目。2列目と同様
    SplitDraw pic2, pic3, pic4, 127, 0, 0, 32
                                       ^^^^^^
    For n = 1 To 3
        SplitDraw pic2, pic3, pic4, 127, n * 57 - 5 - 28
    Next n
    For n = 0 To 3
    '5列目。右端の隙間を埋める
        SplitDraw pic2, pic3, pic4, 175, n * 57 - 5
    Next n

  '敷き詰めのための関数
    Private sub SplitDraw(......,
        optional x0 as long=0,optional y0 as long=0)
    ^^^^^^^^^^^^^^^^^^^^^^^^
    lngRet = BitBlt(pic1.hDC, X, Y, _
                    pic3.ScaleWidth-x0, pic3.ScaleHeight-y0, _
                                   ^^^                  ^^^
                    pic3.hDC, x0, y0, SRCERASE)
                             ^^^ ^^^
    lngRet = BitBlt(pic1.hDC, X, Y, _
                    pic2.ScaleWidth-x0, -pic2.ScaleHeight-y0, _
                                   ^^^                   ^^^
                    pic2.hDC, x0, y0, SRCINVERT)
                             ^^^ ^^^
    end sub

まだ「ドット抜け、速さ」ついて課題は残っていますが、お陰様で一段落です。
ありがとうございました。