mieki256's diary



2024/02/09(金) [n年前の日記]

#1 [basic] FreeBASICで反転描画。その4

Windows10 x64 22H2 + FreeBASIC 1.10.1 32bit で、標準機能のグラフィック描画で反転描画する方法について調べてる。

imgput() を改造して、透明色を有効にしたり、描画元領域を指定できるようにしてみたけれど、ウインドウ外に描画すると見た目がおかしくなることに気づいて修正していた。水平垂直反転の描画時は動作するようになったと思ったら、回転描画時にクラッシュしたりして…。まあ、どうにか動く状態になった気がする。

実処理部分をライブラリファイル(lib*.a)化して、ヘッダファイル(.bi)を include すれば使えるようにしてみた。ライブラリファイルは gas ではなく gcc + 最適化有効でコンパイルしたので、Put() と比べて4倍遅かったのが、1.5〜2倍程度の遅さに改善された。

せっかくだから、現状の成果を置いときます。

_imgputt2_20240209.zip

ただ、 _元ファイル(imgput()) のライセンスが不明で…。「改良する元ソースにはなるだろう」とか書いてあった気もするから、自由に使っていいのではと勝手に思ってるけど…。

サンプルのスクリーンショット :

同梱のサンプルファイルを実行した際の結果は以下。

ss_test_imgputt.png

ss_bench_imgputt.png

ss_simple_sample.png

ss_move_sample.png

ライブラリのソースとヘッダーファイル :

ライブラリのソースとヘッダーファイルは以下。

_imgputt.bas
_imgputt.bi

簡単な使い方 :

簡単なサンプル。imgputt.bi を include すれば、imgputt() が使えるようになる。

_simple_sample.bas
#include once "imgputt.bi"

screenres 512, 288, 32
Dim As Any Ptr p = ImageCreate(288, 288)
Bload "obj_24bit.bmp", p

Put (10, 10), p, (0, 96) - Step(96, 96), Trans

imgputt(p, , 10, 10 + 100, TRANSFORM_VFLIP, IMGPUT_TRANS, 0, 96, 96, 96)

imagedestroy p
sleep

#2 [basic] FreeBASICでbmp画像のサイズを調べたい

FreeBASIC を使って画像の反転描画の実験をしていた際、指定したサイズで画像が描画されなくて、数時間悩んでしまった。

原因はしょーもないことだった。bload でbmp画像を読み込むその前に、ImageCreate() を使って画像と同じサイズの画像バッファを用意しなきゃいけないのだけど。以前の実験で使ってた、小さい画像のサイズのままだった、というオチで…。

でも、そのあたりは自動でやってほしいよなあ…。フツー(?)のライブラリなら、画像ファイル名を指定するだけで、サイズ取得、バッファ確保、ファイル読み込みを全部やってくれるものではないか…。

ということで、bmp画像のファイル名を指定するだけで、サイズ取得、バッファ確保、画像をロードする処理を書いてみた。

環境は Windows10 x64 22H2 + FreeBASIC 1.10.1 32bit。

ソース :

実処理部分。

_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度ファイルをオープンしてメモリ上に読み込んでから、サイズ取得、バッファ確保、バッファ上に展開、とかするのが妥当なのだろうな…。画像ファイルをオープンする処理と、メモリ上に存在する画像データを展開する処理は、別れてたほうが都合がいいはず。

参考ページ :

_BMP ファイルフォーマット
_BMP画像のファイル構造(ヘッダ部・データ部) | 西住工房

bmp画像の横幅、縦幅は、ファイル先頭を0バイト目とした場合、18バイト目から4バイトずつ並んでる。

FreeBASIC で get を使って、ファイルから値を読み込む際、一番最初のバイトにアクセスするなら1を指定するので…。前述のソースでは以下のような記述になっている、とメモ。
    Get #f, 19, w    ' get width
    Get #f,   , h    ' get height

以上、1 日分です。

過去ログ表示

Prev - 2024/02 - Next
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project