JavaScriptとCanvasで、Photoshopなどによくある「トーンカーブ」用の部品を自作してみた。
トーンカーブとは次のようなものだが、
Photoshop > トーンカーブの補正
helpx.adobe.com/jp/photoshop/using/curves-adjustment.html
GIMP > 5.8. トーンカーブ
docs.gimp.org/2.8/ja/gimp-tool-curves.html
曲線補間の方式がいろいろあって悩ましく、日本語で見つかっただけでも
- ガウス・ジョルダン法
- ラグランジュ補間
- ベジェ曲線
- スプライン曲線
- Bスプライン
- Catmull-Romスプライン
- 秋間スプライン
- 離散コサイン/フーリエ変換とかも?
などなど。。。
Photshopはどうやって曲線を描画してるのか?・・情報がなくてわからない。
GIMPはソースコードを軽く見たところ、2点ずつ「円弧」を描画してるのかな?「Cairo」というライブラリの cairo_arc 関数を使ってるように見えた。
ただGIMPの曲線は、点が隅の方にある時になんかちょっと違和感のある挙動をする。実用上問題ないレベルで高速軽量な方式を選択してるのかもしれない。
とりあえずトーンカーブ曲線の実装アルゴリズムは
- 定石のような方法は特にない
- ようするに0~255の整数を、なにか曲線に沿った値に変換できれば何でもよい
ということかもしれない。
というわけであれこれ適当に試した結果いちばんうまくいったのは「2点ずつ3次ベジェ曲線で補間する」方式だった。
-
- PhotoshopやGIMPのトーンカーブのような部品。
- 曲線は2点ずつ3次ベジェ曲線でなめらかに結ぶ。
- 曲率を指定できる。曲率0=直線からだんだんなめらかな曲線に変化する。
- 出力の数値範囲と分解数を任意に指定可。(負の値もOK!)
- 初期アンカーポイントいくつでも指定可。
- 背景ヒストグラム(棒グラフ)指定可。
- 任意の長方形にも設定可、大きさも任意。
出力範囲:0~255(256分解)
曲率0.3
出力範囲:-1~1(100分解)
曲率0.3
出力範囲:-100~100(200分解)
曲率0.3
出力範囲:-30~0(10分解)
曲率0.3
はぁはぁ・・なんとかそれっぽく動いてるけど、処理負荷が高いかもなー・・。