グレースケール・セピア変換 <TOP>
フルカラー画像をYIQ変換しグレースケール・セピアで表示します。
CreateCompatibleDC
互換性のあるメモリデバイスコンテキストを作成
CreateCompatibleBitmap
デバイスコンテキストと互換性のあるビットマップを作成
SelectObject
指定されたデバイスコンテキストのオブジェクトを選択
DeleteDC
指定されたデバイスコンテキストを削除
DeleteObject
グラフィックスオブジェクトを削除し、システムリソースを解放
BitBlt
画像のビットブロック転送
GetPixel
ピクセルのカラー値を取得
SetPixelV
指定の位置のピクセルを指定のカラーに最も近いカラー値に設定
YIQ変換
YIQ変換とは、カラー画像の表色系の一つで、Y は輝度、I は肌色を含むオレンジからシアンにかけての色調、Q はそれ以外の色を表す。
RGBからYIQ変換を行うには次の式で表される。
Y=0.299*R+0.587*G+0.114*B
'================================================================ '= グレースケールセピア変換 '= (GrayScale.bas) '================================================================ #include "Windows.bi" ' 指定されたデバイスコンテキストに関連するデバイスと互換性のあるメモリデバイスコンテキストを作成 Declare Function Api_CreateCompatibleDC& Lib "gdi32" Alias "CreateCompatibleDC" (ByVal hDC&) ' デバイスコンテキストと互換性のあるビットマップを作成 Declare Function Api_CreateCompatibleBitmap& Lib "gdi32" Alias "CreateCompatibleBitmap" (ByVal hDC&, ByVal nWidth&, ByVal nHeight&) ' 指定されたデバイスコンテキストのオブジェクトを選択 Declare Function Api_SelectObject& Lib "gdi32" Alias "SelectObject" (ByVal hDC&, ByVal hObject&) ' 指定されたデバイスコンテキストを削除 Declare Function Api_DeleteDC& Lib "gdi32" Alias "DeleteDC" (ByVal hDC&) ' ペン、ブラシ、フォント、ビットマップ、リージョン、パレットのいずれかの論理オブジェクトを削除し、そのオブジェクトに関連付けられていたすべてのシステムリソースを解放します。オブジェクトを削除した後は、指定されたハンドルは無効になります。 Declare Function Api_DeleteObject& Lib "gdi32" Alias "DeleteObject" (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&) ' 指定された座標のピクセルのRGB値を取得 Declare Function Api_GetPixel& Lib "gdi32" Alias "GetPixel" (ByVal hDC&, ByVal X&, ByVal Y&) ' 指定の位置のピクセルを指定のカラーに最も近いカラー値に設定 Declare Function Api_SetPixelV& Lib "gdi32" Alias "SetPixelV" (ByVal hDC&, ByVal X&, ByVal Y&, ByVal crColor&) ' 指定されたウィンドウのクライアント領域または画面全体を表すディスプレイデバイスコンテキストのハンドルを取得。その後、GDI 関数を使って、返されたデバイスコンテキスト内で描画を行える Declare Function Api_GetDC& Lib "user32" Alias "GetDC" (ByVal hWnd&) ' デバイスコンテキストを解放 Declare Function Api_ReleaseDC& Lib "user32" Alias "ReleaseDC" (ByVal hWnd&, ByVal hDC&) #define SRCCOPY &HCC0020 'そのまま転送 #define DSTINVERT &H550009 'コピー先を反転してコピー Var Shared Picture1 As Object Var Shared Picture2 As Object Var Shared Radio1 As Object Var Shared Radio2 As Object Var Shared Button1 As Object Picture1.Attach GetDlgItem("Picture1") Picture2.Attach GetDlgItem("Picture2") Radio1.Attach GetDlgItem("Radio1") : Radio1.SetFontSize 14 Radio2.Attach GetDlgItem("Radio2") : Radio2.SetFontSize 14 Button1.Attach GetDlgItem("Button1") : Button1.SetFontSize 14 Var Shared Bitmap As Object BitmapObject Bitmap Var Shared hDC1 As Long Var Shared hDC2 As Long Var Shared Flag As Byte '================================================================ '= '================================================================ Declare Function GraySepiaBltSub(ByVal lngColor As Long) As Long Function GraySepiaBltSub(ByVal lngColor As Long) As Long On Error Goto *Er_Trap Var Ret As Long '色をRGBに分割し、YIQ変換を実行 Ret = (lngColor And &HFF) * 0.299 + ((lngColor And &HFF00) / 256) * 0.587 + ((lngColor And &HFF0000) / 65536) * 0.114 'RGB値が0〜255の範囲に収まるようにする If Ret >= 255 Then Ret = 255 Else If Ret <= 0 Then Ret = 0 End If '変換した値を返す If Flag = 0 Then GraySepiaBltSub = RGB(Ret, Ret, Ret) 'グレースケール Else GraySepiaBltSub = RGB(Ret + 30, Ret, Ret - 30) 'セピア End If Exit Function *Er_Trap Resume Next End Function '================================================================ '= '================================================================ Declare Sub GraySepiaBlt(ByVal srchDC As Long, ByVal srcLeft As Long, ByVal srcTop As Long, ByVal srcWidth As Long, ByVal srcHeight As Long, ByVal hDC2 As Long, ByVal trgLeft As Long, ByVal trgTop As Long ) Sub GraySepiaBlt(ByVal srchDC As Long, ByVal srcLeft As Long, ByVal srcTop As Long, ByVal srcWidth As Long, ByVal srcHeight As Long, ByVal hDC2 As Long, ByVal trgLeft As Long, ByVal trgTop As Long ) On Error Goto *Er_Trap Var lX As Long Var lY As Long Var Ret As Long Var mhDC As Long Var hBmp As Long 'メモリDCを作成 mhDC = Api_CreateCompatibleDC(srchDC) 'ビットマップオブジェクトの作成 hBmp = Api_CreateCompatibleBitmap(srchDC, srcWidth, srcHeight) 'メモリDCへビットマップを割付 Ret = Api_SelectObject(mhDC, hBmp) 'メモリDCへ画像をコピー Ret = Api_BitBlt(mhDC, 0, 0, srcWidth, srcHeight, srchDC, srcLeft, srcTop, SRCCOPY) '色情報の読み込み及びYIQ変換処理 For lY = 0 To srcHeight - 1 For lX = 0 To srcWidth - 1 Ret = Api_SetPixelV(mhDC, lX, lY, GraySepiaBltSub(Api_GetPixel(mhDC, lX, lY))) Next lX Next lY '対象のDCにメモリDCをコピー Ret = Api_BitBlt(hDC2, trgLeft, trgTop, srcWidth, srcHeight, mhDC, 0, 0, SRCCOPY) *Er_Trap 'メモリDCの削除 Ret = Api_DeleteDC(mhDC) 'ビットマップオブジェクトの削除 Ret = Api_DeleteObject(hBmp) End Sub '================================================================ '= '================================================================ Declare Sub Mainform_Start edecl () Sub mainform_Start() 'Picture1にBitmap読込 Bitmap.LoadFile "flower.bmp" Picture1.DrawBitmap Bitmap, 0, 0 Bitmap.DeleteObject End Sub '================================================================ '= '================================================================ Declare Sub Button1_on edecl () Sub Button1_on() 'Picture1のデバイスコンテキスト取得 hDC1 = Api_GetDC(Picture1.GethWnd) hDC2 = Api_GetDC(Picture2.GethWnd) If Radio1.GetCheck = 1 Then Flag = 0 Else Flag = 1 SetMousePointer 2 Picture2.Cls 'グレースケール・セピア変換実行 GraySepiaBlt hDC1, 0, 0, Picture1.GetWidth, Picture1.GetHeight, hDC2, 0, 0 SetMousePointer 0 'デバイスコンテキスト解放 Ret = Api_ReleaseDC(Picture1.GethWnd, hDC1) Ret = Api_ReleaseDC(Picture2.GethWnd, hDC2) End Sub '================================================================ '= '================================================================ While 1 WaitEvent Wend Stop End