画像のグレイスケール化

30分プログラム、その723。Bitmapを書き出してみよう - みずぴー日記で作ったビットマップ読み書きモジュールを使って、画像のグレイスケール化をやってみた。


左のカラフルなハワイの画像をグレースケール化すると、右のようなグレイスケール画像になる。
ホントは、ピクセルごとの処理を並列化するつもりだったことを、作ってから思いだした。まあそれはまたの機会ということで。

使い方

1> c("grayscale").
2> grayscale:test().

ソースコード

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

max(A,B,C) ->
    erlang:max(A,erlang:max(B,C)).

min(A,B,C) ->
    erlang:min(A,erlang:min(B,C)).

grayscale({R,G,B}) ->
    Y = erlang:trunc((max(R,G,B) - min(R,G,B)) / 2),
    {Y,Y,Y}.

group(_,[]) ->
     [];
group(N,Xs) ->
    {Ys, Zs} = lists:split(N,Xs),
    [ list_to_tuple(Ys) | group(N,Zs)].

data_to_color_list(Data) ->
    group(3,binary_to_list(Data)).

color_list_to_data(Xs) ->
    list_to_binary(lists:concat(lists:map(fun tuple_to_list/1,Xs))).

test() ->
    {ok,Bin} = file:read_file("sample.bmp"),
    {X,Y,Data} = bitmap:read(Bin),
    Colors = data_to_color_list(Data),
    Grayscales = lists:map(fun grayscale/1,Colors),
    Data2 = color_list_to_data(Grayscales),
    bitmap:write_file("sample2.bmp",{X,Y,Data2}).