仮想計算機構

IT業界と無縁な派遣社員のブログ

グラフィックスの下準備 その2

以前の記事*1でputbytesなる関数を定義しました。これは奥村晴彦さんの本に記載のプログラムをSchemeで書き直したものです。今回はその続きで、grBMP.c (奥村本 p.63)のScheme版を完成させます。

といってもputbytesを作った時点でほぼ完成しており、あとはそれをうまく組み合わせただけです。プログラムは以下のとおりです。

#| grBMP.scm |#
(define XMAX 640)
(define YMAX 400)
(use gauche.array)

(define BLACK (string->number "000000" 16))
(define WHITE (string->number "ffffff" 16))
(define RED (string->number "ff0000" 16))
(define GREEN (string->number "00ff00" 16))
(define BLUE (string->number "0000ff" 16))

(define gr_screen (make-array (shape 0 YMAX 0 XMAX) 0))

(define (putbytes f n x)
    (use scheme.bitwise)
    (do 
        ([i 0 (+ i 1)])
        ([= n i] )
        (begin
            (write-byte (bitwise-and x 255) f)
            (set! x (arithmetic-shift x -8))
        )
    )
)

(define (gr_dot x y color)
    (if (and (and (<= 0 x) (< x XMAX))
             (and (<= 0 y) (< y YMAX)))
        (array-set! gr_screen x y color)
    )
)
(define (gr_clear color)
    (array-for-each-index gr_screen (^(i j) (gr_dot i j color)))
)
(define (gr_BMP fname)
    (define f (open-output-file fname))
    (display "BM" f)
    (putbytes f 4 (+ (* XMAX YMAX 454))
    (putbytes f 4 0)
    (putbytes f 4 54)
    (putbytes f 4 40)
    (putbytes f 4 XMAX)
    (putbytes f 4 YMAX)
    (putbytes f 2 1)
    (putbytes f 2 32)
    (putbytes f 4 0)
    (putbytes f 4 (* XMAX YMAX 4))
    (putbytes f 4 3780)
    (putbytes f 4 3780)
    (putbytes f 4 0)
    (putbytes f 4 0)
    (array-for-each-index gr_screen (^(i j) 
        (putbytes f 4 (array-ref gr_screen i j))))
    (close-output-port f)
)

上記のプログラムを利用するにはinclude*2が一番楽そうです。また、今回は使用していませんが、loadもまた別の機会に使ってみたいところです。

さて、気を取り直して以下のコードで実際に画像を作ってみます。

#| main.scm |#
(include "grBMP.scm")
(gr_BMP "test.bmp")

main.scmを実行すると同じディレクトリ配下にBMP形式のファイルができました。さっそく開いて確認してみましょう。

f:id:riverta1992:20200428211916j:plain

はい黒です。まごうことなき黒 (600 x 400)です。gr_screenを0で初期化しているので当然の結果です。これだけ苦労してできたのが真っ黒な画像。。。と思ってしまいますが、自分の今後のベースになるので引き続き頑張りたいところです。

 

参考文献