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
-
- wavDist :: ImageM
polarChecker :: Int -> Region
次の例は左から順に polarChecker 2, polarChecker 3,
polarChecker 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 です。
- lerpI :: ImageM -> ImageC -> ImageC -> ImageC
-
lerpI im0 im1 im2 は、
im0の濃さにしたがって、im1 と im2 を混ぜ合わせます。
次の例は lerpI wavDist blueI redI です。
- 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です。
- compR :: Region -> Region
- 補領域です
- capR, cupR, xorR, setminusR :: Region -> Region -> Region
- 共通部分、論理和、排他的論理和、差です
- radReg :: Double -> Region
-
次の例は左から順に radReg 2, radReg 3, radReg 5です。
- shiftXor :: Double -> Filter Bool
-
領域を少しずらして XOR をとります。
次の例は cond (shiftXor 2.6 altRings) greenI redIです。
- xorgon :: Int -> Double -> Region -> Region
- shiftXor の n 個への拡張です。
次の例は cond (xorgon 8 (7/4) altRings) cyanI magentaIです。
- crop :: Region -> FilterC
- 領域にしたがって、画像を切り落とします
- radInvert :: Image a -> Image a
- 単位円の内側と外側を“ひっくりかえし”ます。
次の例は radInvert (uscale 0.5 checker)です。
- rippleRad :: Double -> Double -> Image a -> Image a
- 円周に沿って波立たせます。次の例は rippleRad 8 0.3 (lerpI wavDist magentaI yellowI) です。
- circleLimit :: Double -> FilterC
-
次の例は circleLimit 10 (cond checker yellowI cyanI) です。
Koji Kagawa