らんたいむ ますこっと スクリプト Part 2
2回目は、ウインドウをくりぬくための準備。
指定したビットマップのうちの、指定した範囲からウインドウリージョンを取得するメソッドです。
なお、ウインドウハンドルを取得するメソッドと同様、実際には専用のクラス内で定義しておりますが、その部分は省略しております。
def createRgn(bitmap, x, y, width, height) rgn = createRectRgn(0, 0, width, height) for yi in 0 ... height x0 = -1 for xi in 0 ... width c = bitmap.get_pixel(x + xi, y + yi) a = c.alpha if x0 >= 0 if a >= 255 diffRgn(rgn, x0, yi, xi, yi + 1) x0 = -1 end else if a < 255 x0 = xi end end end if x0 >= 0 diffRgn(rgn, x0, yi, width, yi + 1) end end return rgn end
内部で使っている、ウインドウリージョンからある範囲を外すメソッドです。
def diffRgn(rgn, left, top, right, bottom) diff_rgn = createRectRgn(left, top, right, bottom) combineRgn(rgn, rgn, diff_rgn, RGN_DIFF) deleteObject(diff_rgn) end
使っているWindows APIの定義はコレ。RGN_DIFFとかの定数は適当に調べて使って下さい。
def createRectRgn(left, top, right, bottom) api = Win32API.new("gdi32.dll", "CreateRectRgn", "l l l l", "l") return api.call(left, top, right, bottom) end def combineRgn(dest, src1, src2, mode) api = Win32API.new("gdi32.dll", "CombineRgn", "l l l l", "l") return api.call(dest, src1, src2, mode) end def deleteObject(obj) api = Win32API.new("gdi32.dll", "DeleteObject", "l", "l") return api.call(obj) end
私も時々掲示板に出没する、マルペケつくろーどっとコムさんの「ビットマップでリージョンを作成する」の記事を参考にしています。
ほとんどそのままですが、画像の一部分のみからリージョンを作成するようにしたり、1ドットずつを処理していたところを、1行分でまとめられるだけ処理するようにしたりしています。
一部分からリージョンを作れるようにしたのは、ランタイムの画像からそのままリージョンを作りたかったら。一々細切れにしてもいいんだけどね。
1行分まとめては、多分、その方が効率がいい気がしたから。まぁ、誤差の範囲な気がしますし、大差はないでしょうけど。そのまま、っていうのが気に入らないので、少しだけど改良したのです。
次回は、このリージョンを使ってあれこれして終わり、の予定です。