UWSCでビットマップ画像情報の取得(およびバイナリの読込みサンプル)

ADODB.Streamを使うとバイナリの読込みが可能。
FileSystemObjectでも制限付きながら可能。
なので、ビットマップ情報の取得(Windows用のみで適当なの)を書いてみた。
使い方は、「Bitmap.Open("a.bmp")」といった感じ。


ちなみに、バイナリーの読み書きをしたい場合は、
UWSCでバイナリーファイルの読み書き - じゅんじゅんのきまぐれ
こちらをどうぞ。

// Bitmapのヘッダー部読み込みモジュール
//  ( 0,2):BM
//  ( 2,4):File size
//  (10,4):画像データへのオフセット(色テーブルのため)
//  (14,4):情報ヘッダーサイズ(Windows用は40、かな)
//  (18,4):幅
//  (22,4):高さ
//  (28,2):色数、24Bitフルカラーの場合は、24
MODULE Bitmap
	CONST NoErr = 0
	CONST Error = 1
	CONST ErrFileNotFound = 2
	CONST ErrNotBitmap = 3

	PUBLIC bmHead = 0
	PUBLIC fileSize = 0
	PUBLIC offset = 0
	PUBLIC width = 0
	PUBLIC height = 0
	PUBLIC color = 0

	PROCEDURE Init()
		bmHead = 0
		fileSize = 0
		offset = 0
		width = 0
		height = 0
		color = 0
	FEND

	PROCEDURE Set(i, data, base)
		// シーケンシャルに呼ばれる想定
		// 厳密にはこれじゃダメだけど適当
		IFB i < 2 THEN
			bmHead = bmHead + data * POWER(base, i)
		ELSEIF i < 10 THEN
			fileSize = fileSize + data * POWER(base, i - 2)
		ELSEIF i < 14 THEN
			offset = offset + data * POWER(base, i - 10)
		ELSEIF i < 18 THEN
			// nop
		ELSEIF i < 22 THEN
			width = width + data * POWER(base, i - 18)
		ELSEIF i < 26 THEN
			height = height + data * POWER(base, i - 22)
		ELSEIF i < 28 THEN
			// nop
		ELSEIF i < 30 THEN
			color = color + data * POWER(base, i - 28)
		ENDIF
	FEND

	FUNCTION Check()
		RESULT = NoErr
		// 19778 = 0x4D42 -> LittleEndian -> 'BM'
		IF (bmHead <> 19778) OR (fileSize <= offset) THEN RESULT = ErrNotBitmap
	FEND

	FUNCTION Open(path)
		RESULT = Error
		Init()
		DIM objStream = CREATEOLEOBJ("ADODB.Stream")
		objStream.Open()
		objStream.Type = 1	// 1:Binary 2:Text
		TRY
			objStream.LoadFromFile(path)
		EXCEPT
			RESULT = ErrFileNotFound
		ENDTRY

		IFB RESULT = Error THEN
			DIM i = 0, m = 32
			WHILE !objStream.EOS AND i < m
				Set(i, ASC(objStream.Read(1)), 256)
				i = i + 1
			WEND
			RESULT = Check()
		ENDIF

		objStream.Close()
	FEND
	FUNCTION Open2(path)
		RESULT = Error
		Init()
		DIM fso = CREATEOLEOBJ("Scripting.FileSystemObject")
		DIM objStream
		TRY
			objStream = fso.OpenTextFile(path, 1, FALSE, -1)	// Unicode形式なら2Byteずつで扱える
		EXCEPT
			RESULT = ErrFileNotFound
		ENDTRY

		IFB RESULT = Error THEN
			DIM i = 0, m = 32
			WHILE !objStream.AtEndOfStream AND i < m
				Set(i, ASC(objStream.Read(1)), 65536)
				i = i + 2
			WEND
			objStream.Close()
			RESULT = Check()
		ENDIF
	FEND

ENDMODULE