CHKIMG

タグ: , , ,

指定画像が画面上にあるかチェックし、あればその情報を返します。

構文
  1. Boolean = CHKIMG( [画像名, 透過色/色無視, x1, y1, x2, y2, 番号, 色幅] )
引数
画像名
画像ファイル名(BMP形式のみ) (画像名を省略した場合はクリップボードから)
透過色/色無視
0
指定なし(デフォルト)
1,2,3,4
左上(1),右上(2),左下(3),右下(4)の1ピクセルの色を透過色として処理
-1
色を無視して形でチェックする
x1, y1, x2, y2
サーチ範囲
番号
複数ある場合に順番を指定 (左上から)
-1
-1が指定された場合はヒットした数を戻値として返し、座標情報は ALL_IMG_X[], ALL_IMG_Y[]に格納
(G_IMG_X、 G_IMG_Yには最後にヒットした位置が入る)
色幅
チェックに色幅を持たせる (色無視指定時もしくは 16bitカラー以下の場合は無効)
IMG_MSK_BGR1
各色(BGR)に対し 2/256の色幅を許す
IMG_MSK_BGR2
各色(BGR)に対し 4/256の色幅を許す
IMG_MSK_BGR3
各色(BGR)に対し 8/256の色幅を許す
IMG_MSK_BGR4
各色(BGR)に対し 16/256の色幅を許す
IMG_MSK_B1, 2, 3, 4
青に対し 2/256, 4/256, 8/256, 16/256の色幅を許す
IMG_MSK_G1, 2, 3, 4
緑に対し 2/256, 4/256, 8/256, 16/256の色幅を許す
IMG_MSK_R1, 2, 3, 4
赤に対し 2/256, 4/256, 8/256, 16/256の色幅を許す
演算可
例:IMG_MSK_B1 or IMG_MSK_R3(青に対し 2/256の色幅を許す + 赤に対し 8/256の色幅を許す)
戻値

有ればTRUE、無ければFALSE

TRUE の場合は見つかった座標を特殊変数G_IMG_X、 G_IMG_Y に格納

番号にて -1指定時はヒットした数を返し、座標情報は配列変数 ALL_IMG_X[], ALL_IMG_Y[] に格納(配列はゼロから)

サーチ範囲の座標について

左上が基準(x = 0, y = 0)です。x2, y2はx1, y1より大きい値(x1 < x2 かつ y1 < y2が成り立つ範囲)を指定してください。

アクティブウィンドウの範囲

DIM ID = GETID(GET_ACTIVE_WIN)
DIM x = STATUS(ID, ST_X)
DIM y = STATUS(ID, ST_Y)
DIM width = STATUS(ID, ST_WIDTH)
DIM height = STATUS(ID, ST_HEIGHT)

CHKIMG(“image.bmp”,, x, y, x + width, y + height)

色幅

色幅は24bit以上でないと無視されてしまいます。

ビットの深さは、ファイルを右クリック→[プロパティ]→[詳細]で確認、もしくはgetBitmapで取得できます。

DIM array = getBitmap(path)
PRINT array[3]

以下は左上から(B, G, R) = (180, 174, 255)~(219, 174, 255)の画像を並べています。

以下は上記画像のB成分をまとめた表です。画像の位置と対応しています。

B成分の値
180 181 182 183 184 185 186 187 188 189
190 191 192 193 194 195 196 197 198 199
200 201 202 203 204 205 206 207 208 209
210 211 212 213 214 215 216 217 218 219

以下は(B, G, R) = (200, 174, 255)の画像で、色幅を指定することで上に示したハートを並べた画像にどれだけの誤差までマッチするのかを調べるプログラム。

DIM path = “D:\Desktop\CHKIMG\BGR=200,174,255.bmp”
DIM array[] = “IMG_MSK_BGR”, “IMG_MSK_B”, “IMG_MSK_G”, “IMG_MSK_R”

PRINT “元画像:BGR=200,174,255.bmp”
PRINT 

FOR item IN array
	FOR i = 1 TO 4
		a = item + i
//		PRINT a + “<#TAB>” + CHKIMG(path,,,,,, -1, EVAL(a))
		DIM num = CHKIMG(path,,,,,, -1, EVAL(a))
		PRINT “■” + a
		PRINT “マッチ数:” + num
		FOR n = 0 TO num – 1
			DIM c = PEEKCOLOR(ALL_IMG_X[n] + 25, ALL_IMG_Y[n] + 25)
			DIM r = c AND $FF
			DIM g = (c AND $FF00) / $100
			DIM b = (c AND $FF0000) / $10000
			PRINT r + “, ” + g + “, ” + b
		NEXT
		PRINT
	NEXT
NEXT
結果
元画像:BGR=200,174,255.bmp

■IMG_MSK_BGR1
マッチ数:3
255, 174, 199
255, 174, 200
255, 174, 201

■IMG_MSK_BGR2
マッチ数:7
255, 174, 197
255, 174, 198
255, 174, 199
255, 174, 200
255, 174, 201
255, 174, 202
255, 174, 203

■IMG_MSK_BGR3
マッチ数:15
255, 174, 193
255, 174, 194
255, 174, 195
255, 174, 196
255, 174, 197
255, 174, 198
255, 174, 199
255, 174, 200
255, 174, 201
255, 174, 202
255, 174, 203
255, 174, 204
255, 174, 205
255, 174, 206
255, 174, 207

■IMG_MSK_BGR4
マッチ数:31
255, 174, 185
255, 174, 186
255, 174, 187
255, 174, 188
255, 174, 189
255, 174, 190
255, 174, 191
255, 174, 192
255, 174, 193
255, 174, 194
255, 174, 195
255, 174, 196
255, 174, 197
255, 174, 198
255, 174, 199
255, 174, 200
255, 174, 201
255, 174, 202
255, 174, 203
255, 174, 204
255, 174, 205
255, 174, 206
255, 174, 207
255, 174, 208
255, 174, 209
255, 174, 210
255, 174, 211
255, 174, 212
255, 174, 213
255, 174, 214
255, 174, 215

■IMG_MSK_B1
マッチ数:3
255, 174, 199
255, 174, 200
255, 174, 201

■IMG_MSK_B2
マッチ数:7
255, 174, 197
255, 174, 198
255, 174, 199
255, 174, 200
255, 174, 201
255, 174, 202
255, 174, 203

■IMG_MSK_B3
マッチ数:15
255, 174, 193
255, 174, 194
255, 174, 195
255, 174, 196
255, 174, 197
255, 174, 198
255, 174, 199
255, 174, 200
255, 174, 201
255, 174, 202
255, 174, 203
255, 174, 204
255, 174, 205
255, 174, 206
255, 174, 207

■IMG_MSK_B4
マッチ数:31
255, 174, 185
255, 174, 186
255, 174, 187
255, 174, 188
255, 174, 189
255, 174, 190
255, 174, 191
255, 174, 192
255, 174, 193
255, 174, 194
255, 174, 195
255, 174, 196
255, 174, 197
255, 174, 198
255, 174, 199
255, 174, 200
255, 174, 201
255, 174, 202
255, 174, 203
255, 174, 204
255, 174, 205
255, 174, 206
255, 174, 207
255, 174, 208
255, 174, 209
255, 174, 210
255, 174, 211
255, 174, 212
255, 174, 213
255, 174, 214
255, 174, 215

■IMG_MSK_G1
マッチ数:1
255, 174, 200

■IMG_MSK_G2
マッチ数:1
255, 174, 200

■IMG_MSK_G3
マッチ数:1
255, 174, 200

■IMG_MSK_G4
マッチ数:1
255, 174, 200

■IMG_MSK_R1
マッチ数:1
255, 174, 200

■IMG_MSK_R2
マッチ数:1
255, 174, 200

■IMG_MSK_R3
マッチ数:1
255, 174, 200

■IMG_MSK_R4
マッチ数:1
255, 174, 200

以上の結果から、マッチする色幅は以下のようになることがわかります。

定数名 マッチするBGRの範囲
IMG_MSK_BGR1 (-1, -1, -1)〜(+1, +1, +1)
IMG_MSK_BGR2 (-3, -3, -3)〜(+3, +3, +3)
IMG_MSK_BGR3 (-7, -7, -7)〜(+7, +7, +7)
IMG_MSK_BGR4 (-15, -15, -15)〜(+15, +15, +15)
IMG_MSK_B1 (-1, ±0, ±0)〜(+1, ±0, ±0)
IMG_MSK_B2 (-3, ±0, ±0)〜(+3, ±0, ±0)
IMG_MSK_B3 (-7, ±0, ±0)〜(+7, ±0, ±0)
IMG_MSK_B4 (-15, ±0, ±0)〜(+15, ±0, ±0)
IMG_MSK_G1 (±0, -1, ±0)〜(±0, +1, ±0)
IMG_MSK_G2 (±0, -3, ±0)〜(±0, +3, ±0)
IMG_MSK_G3 (±0, -7, ±0)〜(±0, +7, ±0)
IMG_MSK_G4 (±0, -15, ±0)〜(±0, +15, ±0)
IMG_MSK_R1 (±0, ±0, -1)〜(±0, ±0, +1)
IMG_MSK_R2 (±0, ±0, -3)〜(±0, ±0, +3)
IMG_MSK_R3 (±0, ±0, -7)〜(±0, ±0, +7)
IMG_MSK_R4 (±0, ±0, -15)〜(±0, ±0, +15)

IMG_MSK_RGB(数値) の数値を\(n\)とすると、以下が成り立ちます。

色幅:\((2^{n}-1) \times 2 + 1\)
範囲:\(-(2^{n}-1)〜+(2^{n}+1)\)

エラー

CHKIMGでのヒット数が4096を超えるとエラーになるので、マッチさせる画像を大きくするか、調べる範囲を狭くするなどの対策が必要です。

プログラム実行例

指定した画像が画面上あるかどうか

指定した画像が画面上にあればTrue、なければFalseを返します。

PRINT CHKIMG("image.bmp")
  1. script.function.CHKIMG(1)

指定画像を色を無視してチェックする

指定した画像が画面上にあればTrue、なければFalseを返します。

PRINT CHKIMG("image.bmp", -1)
  1. script.function.CHKIMG(1)

指定した範囲に画像があるかチェック

指定画像が左上の範囲にあればTrue、なければFalseを返します。

PRINT CHKIMG("image.bmp", , 0, 0, G_SCREEN_W / 2, G_SCREEN_H / 2)
  1. script.function.CHKIMG(1)

指定した画像のヒット数を返す

PRINT CHKIMG("image.bmp", , , , , , -1)
  1. script.function.CHKIMG(1)

指定した画像の中央を左クリック

DIM path = "image.bmp"
DIM arr = getBitmap(path)
CHKIMG(path)

BTN(LEFT, CLICK, G_IMG_X + arr[1] / 2, G_IMG_Y + arr[2] / 2)

//////////////////////////////////////////////////
// 【引数】
//   dec : 10進数 
// 【戻値】
//   16進数に変換した値 
//////////////////////////////////////////////////
FUNCTION decToHex(dec)
	RESULT = FORMAT(VAL(dec), 0, -1)
FEND

//////////////////////////////////////////////////
// 【引数】
//   str 
// 【戻値】
// 
//////////////////////////////////////////////////
FUNCTION Endian(str)
	DIM len = LENGTH(str)
	
	IFB !isEven(len) THEN
		str = "0" + str
		len = len + 1
	ENDIF
	
	DIM res = ""
	FOR n = 1 TO len STEP 2
		res = COPY(str, n, 2)  + res
	NEXT
	
	RESULT = res
FEND

//////////////////////////////////////////////////
// 【引数】
//   path : ビットマップ画像のパス 
// 【戻値】
//   配列。0:サイズ(Byte)、1:幅(px)、2:高さ(px)、3:ビットの深さ(bit) 
//////////////////////////////////////////////////
FUNCTION getBitmap(path)
	DIM arr[3]		// 戻り値
	
	DIM Stream = CREATEOLEOBJ("ADODB.Stream")
	Stream.Open()
	Stream.Type = 1		// adTypeBinary
	Stream.LoadFromFile(path)
	DIM tmp = Stream.Read(30)
	Stream.Close()

	// BM(0~1)
	DIM fmt = ""
	FOR n = 0 TO 1
		fmt = fmt + decToHex(tmp[n])
	NEXT

	IFB fmt <> "424D" THEN
		RESULT = ERR_VALUE
		EXIT
	ENDIF
	
	// サイズ(2~5)
	DIM size = ""
	FOR n = 2 TO 5
		size = size + REPLACE(FORMAT(VAL(decToHex(tmp[n])), 2), " ", "0")
	NEXT
	arr[0] = hexToDec(Endian(size))
	
	// 幅(18~21)
	DIM width = ""
	FOR n = 18 TO 21
		width = width + REPLACE(FORMAT(VAL(decToHex(tmp[n])), 2), " ", "0")
	NEXT
	arr[1] = hexToDec(Endian(width))
	
	// 高さ(22~25)
	DIM height = ""
	FOR n = 22 TO 25
		height = height + REPLACE(FORMAT(VAL(decToHex(tmp[n])), 2), " ", "0")
	NEXT
	arr[2] = hexToDec(Endian(height))
	
	// ビットの深さ(28~29)
	DIM bit = ""
	FOR n = 28 TO 29
		bit = bit + REPLACE(FORMAT(VAL(decToHex(tmp[n])), 2), " ", "0")
	NEXT
	arr[3] = hexToDec(Endian(bit))

	RESULT = SLICE(arr)
FEND

//////////////////////////////////////////////////
// 【引数】
//   hex : 16進数 
// 【戻値】
//   10進数に変換した値 
//////////////////////////////////////////////////
FUNCTION hexToDec(hex)
	dec = 0
	hex = STRCONV(hex, SC_LOWERCASE)
	FOR n = 1 TO LENGTH(hex)
		str = COPY(hex, n, 1)
		IFB CHKNUM(str) THEN
			num = str
		ELSE
			num = ASC(str) - 87
		ENDIF
		dec = dec + (num * POWER(16, LENGTH(hex) - n))
	NEXT
	RESULT = dec
FEND

//////////////////////////////////////////////////
// 【引数】
//   expr : 評価する式 
//   truepart : 評価した式がTrueのときに返す値 
//   falsepart : 評価した式がFalseのときに返す値 
// 【戻値】
//   truepart : 評価した式がTrueのとき、falsepart : 評価した式がFalseのとき 
//////////////////////////////////////////////////
FUNCTION IIF(expr, truepart, falsepart)
	IFB EVAL(expr) THEN
		RESULT = truepart
	ELSE
		RESULT = falsepart
	ENDIF
FEND

//////////////////////////////////////////////////
// 【引数】
//   数値 : 整数 
// 【戻値】
//   True : 偶数、False : 奇数 
//////////////////////////////////////////////////
FUNCTION isEven(n)
	IFB n <> VARTYPE(n, VAR_INTEGER) THEN
		RESULT = ERR_VALUE
		EXIT
	ENDIF
	RESULT = IIF(n MOD 2 = 0, TRUE, FALSE)
FEND
  1. udf.getBitmap(2)
  2. script.function.CHKIMG(3)
  3. script.function.BTN(5)
解説
  1. 2行目
    DIM arr = getBitmap(path)
    
    getBitmap関数で画像「image.bmp」の情報を取得しarr配列に格納。
  2. 3行目
    CHKIMG(path)
    
    「image.bmp」を探して見つかったら座標を取得。
  3. 5行目
    BTN(LEFT, CLICK, G_IMG_X + arr[1] / 2, G_IMG_Y + arr[2] / 2)
    
    画像の中央を左クリック。

バックグラウンドでマッチした画像クリックする

MOUSEORG(ID, MORG_DIRECT, MORG_BACK)
CHKIMG("image.bmp", -1)
BTN(LEFT, CLICK, G_IMG_X, G_IMG_Y)
  1. script.function.MOUSEORG(1)
  2. script.function.CHKIMG(2)
  3. script.function.BTN(3)
解説
  1. 1行目
    MOUSEORG(ID, MORG_DIRECT, MORG_BACK)
    
    取得したい画像があるIDを指定。
  2. 2行目
    CHKIMG("image.bmp", -1)
    
    クリックしたい画像のパスを指定。
  3. 3行目
    BTN(LEFT, CLICK, G_IMG_X, G_IMG_Y)
    
    バックグラウンドでマッチした座標をクリック。フォアグラウンドでもクリックされます。