画像を回転させる(U) <TOP>
Bitmap
画像を90度の角度で回転させます。
LoadImage
画像ファイルの読み込み
CreateCompatibleDC デバイスコンテキストを作成
SelectObject 指定されたデバイスコンテキストのオブジェクトを選択
BitBlt
ビットブロック転送を行う
GetObject
オブジェクト取得
CreateCompatibleBitmap
デバイスコンテキストと互換性のあるビットマップを作成
DeleteDC
指定されたデバイスコンテキストを削除
DeleteObject 論理オブジェクトを削除
GetDC
デバイスコンテキストを取得
ReleaseDC
デバイスコンテキストの解放
EditBoxにBmpファイルをドラッグ&ドロップします。
EditBoxは、複数行入力ありに設定しています。
'================================================================ '= 画像を回転させる(U) '= (RotateBitmap.bas) '================================================================ #include "Windows.bi" #define IMAGE_BITMAP 0 'ビットマップ #define LR_LOADFROMFILE &H10 '外部ファイルからロードする #define LR_CREATEDIBSECTION &H2000 'デバイス独立ビットマップとしてロードする #define SRCCOPY &HCC0020 'そのまま転送 #define PI 3.14159 Type BITMAP bmType As Long 'ビットマップ タイプを指定(0) bmWidth As Long 'ビットマップの幅を指定 bmHeight As Long 'ビットマップの高さを指定 bmWidthBytes As Long '1 走査線あたりのバイト数を指定 bmPlanes As Integer 'カラープレーンを指定(通常1) bmBitsPixel As Integer '1 ピクセルを定義するのに必要なビット数を指定 bmBits As Long 'ビット データが格納されているの配列へのポインタを指定 End Type ' 画像ファイルの読み込み Declare Function Api_LoadImage& Lib "user32" Alias "LoadImageA" (ByVal hInst&, ByVal lpszName$, ByVal uType&, ByVal cxDesired&, ByVal cyDesired&, ByVal fuLoad&) ' 指定されたデバイスコンテキストに関連するデバイスと互換性のあるメモリデバイスコンテキストを作成 Declare Function Api_CreateCompatibleDC& Lib "gdi32" Alias "CreateCompatibleDC" (ByVal hDC&) ' 指定されたデバイスコンテキストのオブジェクトを選択 Declare Function Api_SelectObject& Lib "gdi32" Alias "SelectObject" (ByVal hDC&, ByVal hObject&) ' ビットブロック転送を行う。コピー元からコピー先のデバイスコンテキストへ、指定された長方形内の各ピクセルの色データをコピー Declare Function Api_BitBlt& Lib "gdi32" Alias "BitBlt" (ByVal hDestDC&, ByVal X&, ByVal Y&, ByVal nWidth&, ByVal nHeight&, ByVal hSrcDC&, ByVal xSrc&, ByVal ySrc&, ByVal dwRop&) ' オブジェクト取得 Declare Function Api_GetObject& Lib "gdi32" Alias "GetObjectA" (ByVal hObject&, ByVal nCount&, lpObject As Any) ' デバイスコンテキストと互換性のあるビットマップを作成 Declare Function Api_CreateCompatibleBitmap& Lib "gdi32" Alias "CreateCompatibleBitmap" (ByVal hDC&, ByVal nWidth&, ByVal nHeight&) ' 指定されたデバイスコンテキストを削除 Declare Function Api_DeleteDC& Lib "gdi32" Alias "DeleteDC" (ByVal hDC&) ' 論理オブジェクトを削除し、そのオブジェクトに関連付けられていたすべてのシステムリソースを解放 Declare Function Api_DeleteObject& Lib "gdi32" Alias "DeleteObject" (ByVal hObject&) ' 指定されたウィンドウのデバイスコンテキストのハンドルを取得 Declare Function Api_GetDC& Lib "user32" Alias "GetDC" (ByVal hWnd&) ' デバイスコンテキストを解放 Declare Function Api_ReleaseDC& Lib "user32" Alias "ReleaseDC" (ByVal hWnd&, ByVal hDC&) Var Shared Timer1 As Object Var Shared Picture1 As Object Var Shared Picture2 As Object Var Shared Edit1 As Object Var Shared Button1 As Object Timer1.Attach GetDlgItem("Timer1") Picture1.Attach GetDlgItem("Picture1") Picture2.Attach GetDlgItem("Picture2") Edit1.Attach GetDlgItem("Edit1") : Edit1.SetFontSize 14 Button1.Attach GetDlgItem("Button1") : Button1.SetFontSize 14 Var Shared sFileName As String Var Shared hBitmap As Long Var Shared lBMDC As Long Var Shared bm As BITMAP Var Shared Degrees As Long Var Shared phDC1 As Long Var Shared phDC2 As Long '================================================================ '= '================================================================ Declare Function Min(X1 As Long, Y1 As Long) As Long Function Min(X1 As Long, Y1 As Long) As Long If X1 >= Y1 Then Min = Y1 Else Min = X1 End If End Function '================================================================ '= '================================================================ Declare Function Max(X1 As Long, Y1 As Long) As Long Function Max(X1 As Long, Y1 As Long) As Long If X1 >= Y1 Then Max = X1 Else Max = Y1 End If End Function '================================================================ '= '================================================================ Declare Sub RotateBitmap(hBitmapDC As Long, lWidth As Long, lHeight As Long, lRadians As Long) Sub RotateBitmap(hBitmapDC As Long, lWidth As Long, lHeight As Long, lRadians As Long) Var hNewBitmapDC As Long Var hNewBitmap As Long Var lSine As Long Var lCosine As Long Var X1 As Long Var X2 As Long Var X3 As Long Var Y1 As Long Var Y2 As Long Var Y3 As Long Var lMinX As Long Var lMaxX As Long Var lMinY As Long Var lMaxY As Long Var lNewWidth As Long Var lNewHeight As Long Var i As Long Var j As Long Var lSourceX As Long Var lSourceY As Long Var Ret As Long hNewBitmapDC = Api_CreateCompatibleDC(hBitmapDC) lSine = Sin(lRadians) lCosine = Cos(lRadians) X1 = -lHeight * lSine Y1 = lHeight * lCosine X2 = lWidth * lCosine - lHeight * lSine Y2 = lHeight * lCosine + lWidth * lSine X3 = lWidth * lCosine Y3 = lWidth * lSine '新しいBitmapの最大/最小サイズ lMinX = Min(0, Min(X1, Min(X2, X3))) lMinY = Min(0, Min(Y1, Min(Y2, Y3))) lMaxX = Max(X1, Max(X2, X3)) lMaxY = Max(Y1, Max(Y2, Y3)) '新しいBitpamの幅/高さ lNewWidth = lMaxX - lMinX lNewHeight = lMaxY - lMinY '新しい幅/高さで回転するBitmapを作成 hNewBitmap = Api_CreateCompatibleBitmap(hBitmapDC, lNewWidth, lNewHeight) 'デバイスコンテキストのオブジェクトを選択 Ret = Api_SelectObject(hNewBitmapDC, hNewBitmap) '各pixelを計算 For i = 0 To lNewHeight For j = 0 To lNewWidth lSourceX = (j + lMinX) * lCosine + (i + lMinY) * lSine lSourceY = (i + lMinY) * lCosine - (j + lMinX) * lSine If (lSourceX >= 0) And (lSourceX <= lWidth) And (lSourceY >= 0) And (lSourceY <= lHeight) Then Ret = Api_BitBlt(hNewBitmapDC, j, i, 1, 1, hBitmapDC, lSourceX, lSourceY, SRCCOPY) End If Next j Next i '新しいBitmapの幅/高さをリセット lWidth = lNewWidth lHeight = lNewHeight '新しいBitmapにデバイスコンテキストを返す hBitmapDC = hNewBitmapDC 'オブジェクトを削除 Ret = Api_DeleteObject(hNewBitmap) End Sub '================================================================ '= '================================================================ Declare Sub LoadBMPFromFile () Sub LoadBMPFromFile() '初期角度設定 Degrees = 0 sFileName = Edit1.GetWindowText Picture1.Cls Picture2.Cls 'Bitmapをメモリにロード hBitmap = Api_LoadImage(0, sFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE Or LR_CREATEDIBSECTION) '呼び出し失敗の場合終了 If (hBitmap = 0) Then A% = MessageBox("Bitmap Load Error", "Error, Bitmapファイルではありません!", 0, 2) End End If 'ロードしたBitmapのデバイスコンテキストを作成 lBMDC = Api_CreateCompatibleDC(0) '失敗した場合プロシージャを抜ける If (lBMDC = 0) Then A% = MessageBox("Device Context Error", "Error, デバイスコンテキストを作成できません!", 0, 2) Exit Sub End If '作成されたデバイスコンテキストにBitmapをAttach Ret = Api_SelectObject(lBMDC, hBitmap) 'イメージ情報を取得 Ret = Api_GetObject(hBitmap, Len(bm), bm) 'Pictureに描画 Ret = Api_BitBlt(phDC1, 0, 0, bm.bmWidth, bm.bmHeight, lBMDC, 0, 0, SRCCOPY) End Sub '================================================================ '= '================================================================ Declare Sub MainForm_Start edecl () Sub MainForm_Start() phDC1 = Api_GetDC(Picture1.GethWnd) phDC2 = Api_GetDC(Picture2.GethWnd) 'タイマーインターバルセット Timer1.SetInterval 100 Timer1.Enable False End Sub '================================================================ '= '================================================================ Declare Sub Button1_on edecl () Sub Button1_on() 'ファイルからBitmapを読み込む LoadBMPFromFile If Timer1.IsEnabled = -1 Then Timer1.Enable 0 Button1.SetWindowText "Start >>" Else Timer1.Enable -1 Button1.SetWindowText "Stop >>" LoadBMPFromFile End If End Sub '================================================================ '= '================================================================ Declare Sub Timer1_Timer edecl () Sub Timer1_Timer() Var hRotatedBitmapDC As Long Var lWidth As Long Var lHeight As Long Var lRadians As Long Picture2.Cls 'Bitmapイメージの幅/高さを設定 lWidth = bm.bmWidth lHeight = bm.bmHeight '回転角度をラジアンに変換 lRadians = PI * Degrees / 180 'Picture1デバイスコンテキストを回転デバイスコンテキストに hRotatedBitmapDC = phDC1 '新しい角度に回転させる RotateBitmap hRotatedBitmapDC, lWidth, lHeight, lRadians '回転イメージを転送 Ret = Api_BitBlt(phDC2, 0, 0, lWidth, lHeight, hRotatedBitmapDC, 0, 0, SRCCOPY) 'デバイスコンテキストを破棄 Ret = Api_DeleteDC(hRotatedBitmapDC) '角度を90°増加。一巡したら0°に戻す Degrees = Degrees + 90 If Degrees = 360 Then Degrees = 0 End If End Sub '================================================================ '= シェルドロップされたファイル名を取得 '================================================================ Declare Sub Edit1_DropFiles edecl (ByVal DF As Long) Sub Edit1_DropFiles(ByVal DF As Long) Var CN As Long CN = GetDropFileCount(DF) sFileName = GetDropFileName(DF, 0) Edit1.SetWindowText sFileName Button1.SetWindowText "Start >>" End Sub '================================================================ '= '================================================================ Declare Sub MainForm_QueryClose edecl () Sub MainForm_QueryClose() Var Ret As Long Ret = Api_ReleaseDC(Picture1.GethWnd, phDC1) Ret = Api_ReleaseDC(Picture2.GethWnd, phDC2) End End Sub '================================================================ '= '================================================================ While 1 WaitEvent Wend Stop End