2016/03/19(土) [n年前の日記]
#1 [prog] ProcessingでGIMPのシームレスフィルタを再現できた
シームレス画像を作る際の、合成の割合を求めるあたりの式を、自分なりに色々試していたのだけど。どれも上手くいかなくて。
結局、GIMP 2.8.16 のソースをダウンロードして眺めてるうちにそれらしい部分が見つかったので、そのままベタ移植してみたら再現できてしまったのでした。いいのかソレで。
_sketch_make_seamless(Processing.js版)
_sketch_make_seamless.pde (ソース)
GIMPのソースの、plug-ins/common/tile-seamless.c が、シームレスフィルタのソースっぽいですな。昨日探してた時に見つからなかったのは、GIMP 2.9 のソースを眺めてたから、かもしれず。GIMP 2.8.16 のソースをgrepしてみたら、あっさり見つかりました。数式相当が書かれてるのは、おそらく weld_pixels()。そこだけ抜き出してみますが。
結局、GIMP 2.8.16 のソースをダウンロードして眺めてるうちにそれらしい部分が見つかったので、そのままベタ移植してみたら再現できてしまったのでした。いいのかソレで。
_sketch_make_seamless(Processing.js版)
_sketch_make_seamless.pde (ソース)
- マウスボタンを押すと、元画像が表示されます。
- 右クリックすると、生成したシームレス画像がポップアップウインドウで表示されるので、そこから画像保存できます。(Firefox、GoogleChromeで確認)
GIMPのソースの、plug-ins/common/tile-seamless.c が、シームレスフィルタのソースっぽいですな。昨日探してた時に見つからなかったのは、GIMP 2.9 のソースを眺めてたから、かもしれず。GIMP 2.8.16 のソースをgrepしてみたら、あっさり見つかりました。数式相当が書かれてるのは、おそらく weld_pixels()。そこだけ抜き出してみますが。
gdouble a = (ABS(x - width) - 1)/ (gdouble) (width - 1); gdouble b = (ABS(y - height) - 1) / (gdouble) (height - 1); gdouble w; guint i; /* mimic ambiguous point handling in original algorithm */ if (a < 1e-8 && b > 0.99999999) w = 1.0; else if (a > 0.99999999 && b < 1e-8) w = 0.0; else w = 1.0 - a*b/(a*b + (1.0 - a)*(1.0 - b)); for (i = 0; i < bpp; i++) dest1[i] = dest2[i] = (guchar) (w * src1[i] + (1.0 - w) * src2[i]);これでどうしてあのグラデーションが出来上がるのか、さっぱり分からん…。
◎ MathMapにもシームレスフィルタのソースがあった。 :
ちなみに、GIMP に追加して使える
_MathMap
というフィルタの中にも、make seamless という、シームレス画像を作れるフィルタがあって。expressions/Map/Make Seamless.mm がソレ。ちょっとコピペしてみますが。
ただ、GIMPのシームレスフィルタと比べると、滑らかではないというか、斜めに変な線が入ってしまう模様。
# Edge Behaviour must be Wrap filter make_seamless (image in) "Make sure you set `Edge Behaviour' to `Wrap'." ax=abs(x)/X;ay=abs(y)/Y; x1=max(0,ax-ay); y1=max(0,ay-ax); x2=min(1,ax+(1-ay)); y2=min(1,ay+(1-ax)); weight=clamp(1-(ax-x1)/(x2-x1),0,1); lerp(weight,in(xy+XY),in(xy)) end
- x,y が、x,y座標。
- X,Y が、画像の横幅と縦幅。
- clmap(値, 最小値, 最大値) が、値を最小値と最大値の間にするメソッド、かなと。やってることは、min(max(値, 最小値), 最大値) と同じ。
ただ、GIMPのシームレスフィルタと比べると、滑らかではないというか、斜めに変な線が入ってしまう模様。
◎ 合成割合のグラデーション画像生成を実験してた時のソース。 :
せっかく色々試してたので、もったいないから置いときます。
_sketch_seamless_v_chk (Processing.js版)
_sketch_seamless_v_chk.pde (ソース)
_sketch_seamless_v_chk (Processing.js版)
_sketch_seamless_v_chk.pde (ソース)
- 左クリックで次の数式、右クリックで前の数式を選んで、グラデーション画像を表示。
◎ グラデーション画像を読んでグラフを表示するプログラム。 :
グラデーション画像の変化の具合を確認したかったので書いてみたり。GIMPのシームレスフィルタで作成した画像を読み込んで、y座標が変化した際の横方向の値の変化をグラフっぽく表示。
_sketch_seamless_v_chk_graph (Processing.js版)
_sketch_seamless_v_chk_graph.pde (ソース)
こういう値を得られる式を思いつければ再現できるかなと思って眺めてたけど、結局自力では解答に辿り着けなかったわけで。
_sketch_seamless_v_chk_graph (Processing.js版)
_sketch_seamless_v_chk_graph.pde (ソース)
こういう値を得られる式を思いつければ再現できるかなと思って眺めてたけど、結局自力では解答に辿り着けなかったわけで。
[ ツッコむ ]
以上です。