2024/02/09(金) [n年前の日記]
#2 [basic] FreeBASICでbmp画像のサイズを調べたい
FreeBASIC を使って画像の反転描画の実験をしていた際、指定したサイズで画像が描画されなくて、数時間悩んでしまった。
原因はしょーもないことだった。bload でbmp画像を読み込むその前に、ImageCreate() を使って画像と同じサイズの画像バッファを用意しなきゃいけないのだけど。以前の実験で使ってた、小さい画像のサイズのままだった、というオチで…。
でも、そのあたりは自動でやってほしいよなあ…。フツー(?)のライブラリなら、画像ファイル名を指定するだけで、サイズ取得、バッファ確保、ファイル読み込みを全部やってくれるものではないか…。
ということで、bmp画像のファイル名を指定するだけで、サイズ取得、バッファ確保、画像をロードする処理を書いてみた。
環境は Windows10 x64 22H2 + FreeBASIC 1.10.1 32bit。
原因はしょーもないことだった。bload でbmp画像を読み込むその前に、ImageCreate() を使って画像と同じサイズの画像バッファを用意しなきゃいけないのだけど。以前の実験で使ってた、小さい画像のサイズのままだった、というオチで…。
でも、そのあたりは自動でやってほしいよなあ…。フツー(?)のライブラリなら、画像ファイル名を指定するだけで、サイズ取得、バッファ確保、ファイル読み込みを全部やってくれるものではないか…。
ということで、bmp画像のファイル名を指定するだけで、サイズ取得、バッファ確保、画像をロードする処理を書いてみた。
環境は Windows10 x64 22H2 + FreeBASIC 1.10.1 32bit。
◎ ソース :
実処理部分。
_loadbitmapimage.bi
使用サンプル。
_getbitmapsize.bas
使用画像は以下。
_obj_24bit.bmp
_obj_16bit.bmp
_obj_8bit.bmp
_loadbitmapimage.bi
' load bitmap image file
#ifndef __LOADBITMAPIMAGE__
#define __LOADBITMAPIMAGE__
Function LoadBitmapImage(ByRef fname As Const string) As Any Ptr
Dim As Integer f
Dim As Long w, h
' open bitmap file
f = FreeFile()
Open fname For Binary Access Read As #f
If Err > 0 Then Print "Error: Can not open file" : Return 0
Get #f, 19, w ' get width
Get #f, , h ' get height
Close #f
' Print "Bitmap : " & fname & " (w,h)=(" & w & "," & h & ")"
' create image
Dim As Any Ptr img = ImageCreate(w, h, RGB(0, 0, 0))
If img = 0 Then Print "Error: Can not ImageCreate()" : Return 0
' load bitmap to image
bload fname, img
Return img
End Function
#endif
使用サンプル。
_getbitmapsize.bas
' get bitmap image size
#include "loadbitmapimage.bi"
ScreenRes 512, 288, 32
Dim As String fname = "obj_8bit.bmp"
'Dim As String fname = "obj_16bit.bmp"
'Dim As String fname = "obj_24bit.bmp"
' load bitmap image
Dim img As Any Ptr = LoadBitmapImage(fname)
' get image width, height, bpp
Dim As Integer w, h, bpp
ImageInfo(img, w, h, bpp)
Put (0, 0), img
Print "Load: " & fname & " (" & w & ", " & h & ")"
Print "Push Any Key"
ImageDestroy(img)
sleep
使用画像は以下。
_obj_24bit.bmp
_obj_16bit.bmp
_obj_8bit.bmp
◎ 雑感 :
一応動作はしたのだけど、この処理、bmp画像をサイズ取得のためだけに1度オープンしてからクローズして、bload でまたオープンするという、実にトンチキな作りで…。
本来なら、1度ファイルをオープンしてメモリ上に読み込んでから、サイズ取得、バッファ確保、バッファ上に展開、とかするのが妥当なのだろうな…。画像ファイルをオープンする処理と、メモリ上に存在する画像データを展開する処理は、別れてたほうが都合がいいはず。
本来なら、1度ファイルをオープンしてメモリ上に読み込んでから、サイズ取得、バッファ確保、バッファ上に展開、とかするのが妥当なのだろうな…。画像ファイルをオープンする処理と、メモリ上に存在する画像データを展開する処理は、別れてたほうが都合がいいはず。
◎ 参考ページ :
_BMP ファイルフォーマット
_BMP画像のファイル構造(ヘッダ部・データ部) | 西住工房
bmp画像の横幅、縦幅は、ファイル先頭を0バイト目とした場合、18バイト目から4バイトずつ並んでる。
FreeBASIC で get を使って、ファイルから値を読み込む際、一番最初のバイトにアクセスするなら1を指定するので…。前述のソースでは以下のような記述になっている、とメモ。
_BMP画像のファイル構造(ヘッダ部・データ部) | 西住工房
bmp画像の横幅、縦幅は、ファイル先頭を0バイト目とした場合、18バイト目から4バイトずつ並んでる。
FreeBASIC で get を使って、ファイルから値を読み込む際、一番最初のバイトにアクセスするなら1を指定するので…。前述のソースでは以下のような記述になっている、とメモ。
Get #f, 19, w ' get width
Get #f, , h ' get height
[ ツッコむ ]
以上です。