ポク太郎です。
UWSCでは“画像認識”機能が使えます。以降、画像を扱うことが多くなると思いますので、画像の幅、高さを返す関数を用意しておくことに。
画像のフォーマットは多数ありますが、認識に適する非圧縮のビットマップ(.bmp)を使います。
ビットマップ画像の幅と高さを取得するbmp()関数
どんな並び方(フォーマット)で情報が記録されてるかはそれぞれの画像形式で規定。(それぞれの設計者がそれぞれ決めた。)
自分は何モンですよという情報が大抵はファイルの先頭(ヘッダ)に記録→それを読み取ることで幅や高さ、カラー/モノクロの判別が付きます。当てにならない形式もありますが。
ビットマップ画像のフォーマットも仕様として公開→関数内2行目~9行目にメモ。7行目を例にすると“ファイル先頭から数えて18バイト目から4バイト分が幅を記録する部分”という意味。
今回は画像の幅と高さを取得するのが目的ですので、以下がするべき仕事になります。
幅:ファイル先頭18バイト目から4バイト分読み取り10進数に変換。
高:ファイル先頭22バイト目から4バイト分読み取り10進数に変換。
FUNCTION bmp(path)//path:ビットマップファイルのパス
//ビットマップ画像のフォーマット
// 0,2:"BM"(ビットマップという意味)
// 2,4:ファイルサイズ
//10,4:画像データへのオフセット(色テーブル分)
//14,4:情報ヘッダーサイズ(Windows用:40,OS/2用:12)
//18,4:幅
//22,4:高さ
//28,2:色数(24bitフルカラー:24)
DIM get_wh[1]
bin=CREATEOLEOBJ("ADODB.Stream")
bin.Open()
bin.Type=1
bin.LoadFromFile(path)
tmp_info=bin.Read(26)
bin.Close()
FOR i=18 TO LENGTH(tmp_info)-1
IF (i<22)
get_wh[0]=get_wh[0]+tmp_info[i]*POWER(256,i-18)
ELSEIF (i<26)
get_wh[1]=get_wh[1]+tmp_info[i]*POWER(256,i-22)
ENDIF
NEXT
RESULT=SLICE(get_wh,0,LENGTH(get_wh)-1)
FEND
1,25行目 | 1 25 |
FUNCTION bmp(path)//path:ビットマップファイルのパス FEND |
bmp()関数宣言:BMP画像の幅と高さを得る関数 引数path:BMP画像のパス |
||
2~9行目 | 2 3 4 5 6 7 8 9 |
//ビットマップ画像のフォーマット // 0,2:“BM“(ビットマップという意味) // 2,4:ファイルサイズ //10,4:画像データへのオフセット(色テーブル分) //14,4:情報ヘッダーサイズ(Windows用:40,OS/2用:12) //18,4:幅 //22,4:高さ //28,2:色数(24bitフルカラー:24) |
ビットマップ画像のフォーマット(ヘッダ情報)をコメントアウトでメモ。いちいち調べるの面倒なので。 (例)18,4:幅:“18バイト目から4バイト分に幅のデータがある”という意味。 |
||
10行目 | 10 | DIM get_wh[1] |
取得した幅と高さを代入するための配列変数を宣言しておきます。 | ||
11~16行目 | 11 12 13 14 15 16 |
bin=CREATEOLEOBJ(“ADODB.Stream“) bin.Open() bin.Type=1 bin.LoadFromFile(path) tmp_info=bin.Read(26) bin.Close() |
BMP画像のヘッダ情報を読みたいので、バイナリファイルとして読み込みます。ヘッダ情報の内、必要な部分だけを変数に代入します。 12~14行目: バイナリを読み込み 15行目: 配列tmp_infoに27バイト分を代入。(配列に代入される模様) 16行目: バイナリファイルを閉じます。 |
||
17~23行目 | 17 18 19 20 21 22 23 |
FOR i=18 TO LENGTH(tmp_info)–1 IF (i<22) get_wh[0]=get_wh[0]+tmp_info[i]*POWER(256,i–18) ELSEIF (i<26) get_wh[1]=get_wh[1]+tmp_info[i]*POWER(256,i–22) ENDIF NEXT |
配列tmp_infoから目的の幅と高さを10進数で取得する部分です。 i=18からループが始まりますので、 もし22より小さいなら(つまりi=18~21:“幅”なら)19行目を実行せよ もし26より小さいなら(つまりi=22~25:“高さ”なら)21行目を実行せよ 19行目にPOWER(256,i-18)とあります。 BMP画像は幅と高さを記録するのに4バイト分(16進数の2桁を4つ)確保しています。その4バイト分を10進数に直すには、 |
||
24行目 | 24 | RESULT=SLICE(get_wh,0,LENGTH(get_wh)–1) |
SLICE(配列、開始要素番号、終了要素番号) は指定範囲の配列を戻り値として返す関数です。 ※関数の戻り値に配列を使う方法はこちら(配列変数と関数【使い方まとめ】)。 |
ここでは幅と高さだけ取得しましたが、for~next間のif文に条件を付け加え他のヘッダ情報も同様に返すことで取得できるようになります。
画像の幅と高さを得る関数の呼び出しと代入方法
wh=bmp("C:\poku\ポク太郎アイコン.bmp")
width=wh[0]//幅が入る
height=wh[1]//高さが入る
1~3行目 | 1 2 3 |
wh=bmp(“C:\poku\ポク太郎アイコン.bmp“) width=wh[0]//幅が入る height=wh[1]//高さが入る |
配列wh[]に「ポク太郎アイコン.bmp」の幅と高さが代入されます。 wh[0]が幅、wh[1]が高さです。 |
BMP画像の幅と高さを得る関数 | 見つけた指定画像の中心座標を返す関数 | 高圧縮jpegと劣化なしbmp画像を取得する関数 | あいまいな画像認識の前に“できない理由”を調べる |
○ビットマップ画像(.bmp)の幅と高さを取得する関数
コメント