ピクチャーを回転して表示(その2)
                                                         玄関へお回り下さい。   
ピクチャーを回転して表示(90度毎)一部API使用   (089)
   前のと同様ですが、90度と270度の回転に限定して、ピクセル単位の色の
取得と、書込みにAPIを使用して少し描画速度の向上を図っております。
回転だけなら、メモリDCを使ってPictureBoxを1個だけ使ってできるのですが
速度の向上にはあまり貢献せず、拡大・縮小等を組合わせて使用する場合
は、やはり、作業と表示用のPictureBoxを使用した方が便利かと思います。

フォームに Picture1 Picture2 Command1 のコントロールを貼付ておいて
下さい。

フォームの宣言セクションに記入して下さい。
Option Explicit   'SampleNo=089 WindowsXP VB6.0(SP5) 2002.05.17
'ピクセルカラー値を取得する(P489)
Private Declare Function GetPixel Lib "gdi32" _
    (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long
'指定位置のピクセルを指定のカラーに最も近いカラーに設定する(P501)
Private Declare Function SetPixelV Lib "gdi32" _
    (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, _
    ByVal crColor As Long) As Long
'ビットマップを拡大・縮小してコピーする(P504)
Private Declare Function StretchBlt Lib "gdi32" _
    (ByVal hdc 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 nSrcWidth As Long, ByVal nSrcHeight As Long, _
    ByVal vbCopyType As Long) As Long
Private Const SRCCOPY = &HCC0020  'そのままコピー
'回転角度の設定用
Private kakudo As Integer


Private Sub Form_Load()
'別途プロパティで設定しても可
  Form1.ScaleMode = vbPixels
  With Picture1
    .AutoSize = True
    .AutoRedraw = True
    .ScaleMode = vbPixels
    Set .Picture = LoadPicture("test.jpg")
  End With
  With Picture2
    .AutoSize = True
    .ScaleMode = vbPixels
    .AutoRedraw = True
    .Visible = False
  End With
End Sub


Private Sub Command1_Click()
  Command1.Enabled = False
  Dim p1sw As Long  'Picture1.ScaleWidth
  Dim p1sh As Long  'Picture1.ScaleHeight
  Dim p2sw As Long  'Picture2.ScaleWidth
  Dim p2sh As Long  'Picture1.ScaleHeight
  Dim x1  As Long
  Dim y1  As Long
  Dim c  As Long  'カラーコード
  Dim hDC1 As Long  'Picture1.hDC
  Dim hDC2 As Long  'Picture2.hDC
  Dim x As Long
  Dim y As Long

  '回転角度を設定  クリック毎に右回り90度
  kakudo = kakudo + 90
  '元の画像を非表示
  Picture1.Visible = False
  Picture2.Visible = False
  '元の画像を表示
  If kakudo = 360 Then
    kakudo = 0
    Picture1.Visible = True
    Command1.Enabled = True
    Exit Sub
  End If
  If kakudo = 180 Then '180度回転の場合
    With Picture1
      'コピー元と先のピクチャーのサイズを同一に
      Picture2.Height = .Height
      Picture2.Width = .Width
      'コピー元の画像サイズを取得
      p1sh = .ScaleHeight
      p1sw = .ScaleWidth
      'コピー開始位置を取得
      x = .ScaleWidth - 1&
      y = .ScaleHeight - 1&
      hDC1 = .hdc
    End With
    With Picture2
      'コピー先の短形サイズを取得
      p2sh = -.ScaleHeight
      p2sw = -.ScaleWidth
      hDC2 = .hdc
    End With
    'コピーの開始
    StretchBlt hDC2, x, y, p2sw, _
    p2sh, hDC1, 0&, 0&, p1sw, p1sh, SRCCOPY
    Picture2.Visible = True
    Command1.Enabled = True
    Exit Sub
  End If
  '縦横サイズを逆転する
  With Picture2
    .Height = Picture1.Width
    .Width = Picture1.Height
    hDC2 = .hdc
  End With
  With Picture1
    hDC1 = .hdc
    p1sw = .ScaleWidth
    p1sh = .ScaleHeight
  End With
  For x = 0& To p1sw - 1&
    For y = 0& To p1sh - 1&
      If kakudo = 90 Then
        x1 = p1sh - 1& - y
        y1 = x
      Else   '270度
        x1 = y
        y1 = p1sw - 1& - x
      End If
      'カラー情報の取得
      c = GetPixel(hDC1, x, y)
      If c <> -1& Then
      '取得したカラーを指定位置に設定する
        SetPixelV hDC2, x1, y1, c
      End If
    Next y
  Next x
  Picture2.Visible = True
  DoEvents
  Command1.Enabled = True
End Sub


180度回転する部分のコピーの開始位置等を変更する事で、上下・左右の鏡像が
得られます。又サイズを変更する事で、拡大縮小画像が表示できます。    

高速で90度毎に回転させる方法は過去のログの4143番にゆう(U)さんより投稿があります
のでそちらを見て下さい。複雑すぎて私には理解できませんが、使用させて頂いてます。





2002/05/17