FRAN 関数解説

あらまし

FRANは、Conal Elliot と Paul Hudak の ICFP '97 の論文で公表された、 高階関数を用いて、画像やアニメーションを生成するためのライブラリです。

基本的なアイデアは、画像を“座標から色への関数”、アニメーションを “時刻から画像への関数”として扱うことです。 必然的に画像変換は高階関数となります。

オリジナルの FRAN は多くの機能を含んでいるため、 ここで紹介するバージョンは、 私が型などをアレンジ(主として単純化)してしまっているところがあります。

構成ファイル

データ型・関数一覧

基本データ型

type Point = (Double, Double)
2次元座標を表すデータ型です。
type Colour = (Double, Double, Double, Double)
色を表すデータ型です。BGRA の順にそれぞれ 0〜1 の範囲で表します。
type Image a = Point -> a
ジェネリックな画像を表すデータ型です
type ImageC = Image Colour
カラー画像を表すデータ型です
type ImageM = Image Double
モノクロ画像を表すデータ型です。0〜1の範囲で表します。
type Region = Image Bool
白黒二値画像や領域を表すデータ型です
type Filter a = Image a -> Image a
画像の変換を表すデータ型です

IO 関係 その他

getImage :: String -> IO (Maybe (ImageC, (Int, Int)))
getImage url で URL で指定された画像を読み込み ImageC を生成します。 ImageC とともに画像の幅 w と高さ hも返します。 生成された ImageC は原点を中心に (-w/2, -h/2)〜(w/2, h/2)の範囲に配置します。 (つまり、この範囲の外は透明色です。) 取得や生成に失敗した場合は Nothing を返します。
注: 現在は BMP 形式専用です。他の形式の画像を利用したい場合は、 ConvertHub.comのような、 オンライン画像変換サイトを利用して下さい。
image2BMP :: (Double, Double) -> (Int, Int) -> ImageC -> [Word8]
ImageCから BMP形式をバイト列として生成します。 image2BMP (xmax, ymax) (w, h) im で、 画像 imの (-xmax, -ymax)〜(xmax, ymax)の範囲を幅 w ピクセル、高さ h ピクセルの BMP 形式に変換します。
writeOctet :: [Word8] -> String -> IO String
writeOctet octets ext のように使用します。 カレントディレクトリに拡張子 ext を持つファイルを作成し、 バイト列 octets を書き込み、 生成したファイルの名前を返します。

サンプルプログラム

import Fran
import BMP
import BMPRead
import MyIO

main = do Just (lena, (w, h)) <- getImage
                        "http://guppy.eng.kagawa-u.ac.jp/2010/AdvProg/lena.bmp"
          let image = lerpI (uscale 10 wavDist) yellowI lena
              bmp1  = image2BMP (fromIntegral w/2, fromIntegral h/2) (w, h) image
          name <- writeOctet bmp1 ".bmp"
          putStrLn name

上記のプログラムが生成する図形
元画像'/ 生成画像'/
元画像 (lena.bmp)生成画像

基本画像

以下に基本的な画像を紹介します。もちろん画像は単なる関数なので、 自分で定義することもできます。

サンプル画像は断りがなければ (-3.5, -3.5)〜(3.5, 3.5)の範囲を切りとって表示しています。

whiteI, blackI, redI, greenI, blueI, cyanI, magentaI, yellowI :: ImageC
単色の画像です
udisk :: Region
半径 1の円です
xPos, yPos :: Region
x座標が正の領域、y座標が正の領域を表します
vstrip, checker, altRings :: Region
vstrip checker altRings
wavDist :: ImageM
wavDist
polarChecker :: Int -> Region
次の例は左から順に polarChecker 2, polarChecker 3, polarChecker 5です。
2 3 5

画像変換関数

over :: ImageC -> ImageC -> ImageC
透明度を考慮に入れた画像の重ね合わせです
cond :: Region -> Image a -> Image a -> Image a
cond reg im1 im2 は、 領域 regの中では im1、外では im2 になるような画像です。 次の例は cond (polarChecker 3) blueI greenI です。
cond
lerpI :: ImageM -> ImageC -> ImageC -> ImageC
lerpI im0 im1 im2 は、 im0の濃さにしたがって、im1im2 を混ぜ合わせます。 次の例は lerpI wavDist blueI redI です。
cond
bwIm :: Region -> ImageC
領域を白黒の ImageCに変換します
translate, scale :: (Double, Double) -> Filter a
平行移動と拡大(縮小)です
uscale, rotate :: Double -> Filter a
縦横比を保つ拡大と回転(ラジアン単位)です
swirl :: Double -> Filter a
原点から離れるほど大きく回転する渦巻のような変換です。 次の例は左から順に swirl 3 vstrip, swirl 5 vstripです。
3 5
compR :: Region -> Region
補領域です
capR, cupR, xorR, setminusR :: Region -> Region -> Region
共通部分、論理和、排他的論理和、差です
radReg :: Double -> Region
次の例は左から順に radReg 2, radReg 3, radReg 5です。
2 3 5
shiftXor :: Double -> Filter Bool
領域を少しずらして XOR をとります。 次の例は cond (shiftXor 2.6 altRings) greenI redIです。
shiftXor
xorgon :: Int -> Double -> Region -> Region
shiftXor の n 個への拡張です。 次の例は cond (xorgon 8 (7/4) altRings) cyanI magentaIです。
xorgon
crop :: Region -> FilterC
領域にしたがって、画像を切り落とします
radInvert :: Image a -> Image a
単位円の内側と外側を“ひっくりかえし”ます。 次の例は radInvert (uscale 0.5 checker)です。
radInvert
rippleRad :: Double -> Double -> Image a -> Image a
円周に沿って波立たせます。次の例は rippleRad 8 0.3 (lerpI wavDist magentaI yellowI) です。
rippleRad
circleLimit :: Double -> FilterC
次の例は circleLimit 10 (cond checker yellowI cyanI) です。
circleLimit

Koji Kagawa