Bitmapを読んでみよう

30分プログラム、その702。Bitmapを読んでみよう。
Erlangにはバイナリ構文なる便利なやつがあるので、それを使ってビットマップの読み込みをできるようにしてみよう。Erlangで画像処理、とかもおもしろそうだし。

とりあえず、今回は読み込みのみ。そのうち書き出しもやるかも。

使い方

example() ->
    {ok,Bin} = file:read_file("sample.bmp"),
    read(Bin).

ソースコード

-module(bitmap).
-compile([export_all]).

-record(file_header,{
	  size,
	  offset
	 }).

-record(info_header,{
	  width,
	  height,
	  planes,
	  bit_count,
	  compression,
	  size,
	  x,
	  y,
	  used,
	  import
	 }).

-define(DWORD,32/unsigned-little-integer).
-define(WORD,16/unsigned-little-integer).

-define(LONG,32/signed-little-integer).

read_file_header(
  <<$B,$M,
   Size: ?DWORD,
   _Reserved1: ?WORD,
   _Reserved2: ?WORD,
   Offset: ?DWORD >>) ->
    #file_header{size=Size,offset=Offset}.

read_info_header(
  <<40: ?DWORD,
   Width: ?LONG,
   Height: ?LONG,
   Planes: ?WORD, % Planes
   BitCount:?WORD, % BitCount
   Compression :?DWORD, % Compression
   Size : ?DWORD,
   X : ?DWORD,
   Y : ?DWORD,
   Used : ?DWORD,
   Import:?DWORD
   >>) ->
    #info_header{
		  width=Width,
		  height=Height,
		  planes=Planes,
		  bit_count=BitCount,
		  compression=Compression,
		  size=Size,
		  x=X,
		  y=Y,
		  used=Used,
		  import=Import
		 }.

get_bin(Bin, N)->
    {X,_} = split_binary(Bin,N),
    X.

read(Bin) ->
    {Bin1, Bin2} = split_binary(Bin,14),
    FileHeader = read_file_header(Bin1),
    InfoHeader = read_info_header(get_bin(Bin2,40)),
    #file_header{offset=Offset} = FileHeader,
    {FileHeader,InfoHeader,get_bin(Bin,Offset)}.

test() ->
    {ok,Bin} = file:read_file("sample.bmp"),
    read(Bin).