PluginList
*はじめに
psPaintプロジェクトの「超絶転用効かないプラグイン」の説明とソースです。

プロジェクトが一段落付くまでは、変更や修正の足が早いようにFilterFactryで開発してます。
そのうちSDKに手を出すかも知れませんが…出さないか？

以下のソースはそのままFF(FilterFactory or FilterFoundry)で利用可能(なはず)です。

ツッコミ歓迎

SDKをおもちの方で、今回のプロジェクトに協力して同じ機能のプラグインを提供してくださる方、大歓迎

**blackBorderFillOtherColor
[0/0/0](予約色)の境界線を周辺色で置換するフィルタ。

要するに「彩色レイヤ」の境界を周辺色で塗りつぶしてしまうわけです。

当該ピクセルの輝度が0の時、周辺ピクセルを参照して、最初に発見した輝度0以外のピクセルと値を交換します。

現在は、同じルーチンを各チャンネルで実行しているが、輝度で参照して、発見した座標を利用する方が早そうなので後で別ルーチンを作って比較すること。
たぶん比較するまでも無く早くなるはず。

判定数が多いと実行されていない感じががあるので現在周囲8ピクセルの内6ピクセルのみを参照している。
判定範囲を周囲16ピクセルまで拡張したいがどうか？
---(
%RGB-1.0
100
110
120
130
140
150
160
170
i==0 ? (
// (src(x-1,y,0)!=0)? src(x-1,y,z):(
  (src(x-1,y-1,0)!=0)? src(x-1,y-1,z):(
//   (src(x,y-1,0)!=0)? src(x,y-1,z):(
    (src(x+1,y-1,0)!=0)? src(x+1,y-1,z):(
     (src(x+1,y,0)!=0)? src(x+1,y,z):(
      (src(x+1,y+1,0)!=0)? src(x+1,y+1,z):(
       (src(x,y+1,0)!=0)? src(x,y+1,z):(
        (src(x-1,y+1,0)!=0)? src(x-1,y+1,z):
	c
//	))
)))))
):c


i==0 ? (
// (src(x-1,y,0)!=0)? src(x-1,y,z):(
  (src(x-1,y-1,0)!=0)? src(x-1,y-1,z):(
//   (src(x,y-1,0)!=0)? src(x,y-1,z):(
    (src(x+1,y-1,0)!=0)? src(x+1,y-1,z):(
     (src(x+1,y,0)!=0)? src(x+1,y,z):(
      (src(x+1,y+1,0)!=0)? src(x+1,y+1,z):(
       (src(x,y+1,0)!=0)? src(x,y+1,z):(
        (src(x-1,y+1,0)!=0)? src(x-1,y+1,z):c
//	))
)))))
):c


i==0 ? (
// (src(x-1,y,0)!=0)? src(x-1,y,z):(
  (src(x-1,y-1,0)!=0)? src(x-1,y-1,z):(
//   (src(x,y-1,0)!=0)? src(x,y-1,z):(
    (src(x+1,y-1,0)!=0)? src(x+1,y-1,z):(
     (src(x+1,y,0)!=0)? src(x+1,y,z):(
      (src(x+1,y+1,0)!=0)? src(x+1,y+1,z):(
       (src(x,y+1,0)!=0)? src(x,y+1,z):(
        (src(x-1,y+1,0)!=0)? src(x-1,y+1,z):c
//	))
)))))
):c


a
---)
**colorRotation
カラーローテーション

ソリッドカラーのローテーション実験
Y,R-Y,B-Y空間でローテーション
---(
---)
**dotRemoveK
単独黒ピクセルの除去
周囲ピクセルを参照して弧立したピクセルを白に変換
メソッド上はあまり意味ないので廃止予定
---(
%RGB-1.0
100
110
120
130
140
150
160
170
(c==0)&&(cnv(1,1,1,1,1,1,1,1,1,8)==255)?put(255,0):put(c,0),
get(0)

get(0)

get(0)

a
---)

**dotRemoveW
単独白ピクセル除去

周辺ピクセルを参照して流し込み不能な弧立ピクセルおよび先端ピクセルを除去する。
ペイント作業がラクになるので、組み込みの方が良さそう。

ピクセル配置による重みづけは、上下左右に5倍の重みづけを行なって市松配置4ピクセル
までのピクセルを検索
---(
%RGB-1.0
100
110
120
130
140
150
160
170
(c==255)&&(cnv(1,5,1,5,0,5,1,5,1,1)<=1024)?put(0,0):put(c,0),
get(0)

get(0)

get(0)

a
---)
**paintPreProcess
RGB各チャンネルの最小値を取得して一次データとする

一次データをctl(1)-ctl(0)範囲でクリップ・0-255にマッピングしてから　ctl(2)を域値にして二値化する。
-ctl(1)は、[baseClip]	主に描線の芯の太さの調整(default 0)
-ctl(0)は、[bgClip]	線の調子の硬軟および背景ノイズの除去(default 255)
-ctl(2)は、[threshold]	描線の途切れ具合の調整(default 127)
として使用する。
---(
%RGB-1.0
255
0
127
130
140
150
160
170
put(scl(min(min(r,g),b),ctl(1),ctl(0),0,255)<ctl(2)? 0:255,0),
get(0)

get(0)

get(0)

a
---)
**pickupColor

**pickupX
チャンネル操作で各チャンネルの抽出を行なうフィルタ。

Xは、各チャンネルの頭文字と入れ替え

-pickupC	シアン
-pickupG	緑
-pickupB	青
-pickupM	マゼンタ
-pickupR	赤
-pickupY	黄色
現在以下のフィルタが有る。


この方式は彩度の評価が甘いため、明色・暗色で分離が甘くなるので分離方式を再検討中

**pickupGray
グレー（無彩色）部分の抽出を行なうフィルタだったけど、前処理が必須のなのに加えて、下の"pickupK"の方が分離がよいので廃止しました。

---(
%RGB-1.0
100
110
120
130
140
150
160
170
0

0

0

u+v==0 ? 255-i :0
---)

**pickupK
現在のレイヤから無彩色の部分を抽出するフィルタ
RGB各チャンネルの最大値を反転させ、指定値でスケーリングしてアルファチャンネルにしている。
RGBプレーンの色値は[0/0/0](予約値)の黒
コントローラは、スケーリングする指定値　上限と下限
---(
%RGB-1.0
225
0
120
130
140
150
160
170
0

0

0

scl(255-max(max(r,g),b),ctl(1),ctl(0),0,255)

---)
**punchOutRed
細線化を高速にする為の補助フィルタ
細線化処理をRチャンネルだけに行なっているので、最後にまとめてＲチャンネルを他のチャンネルに複製してモノクロにしている。
---(
%RGB-1.0
100
110
120
130
140
150
160
170
r

r

r

a

---)
**punchOutWhite
抜き部分の白[255/255/255](予約色)を検出してアルファチャンネルを抜くフィルタ。

ほぼアニメ専用ですな
---(
%RGB-1.0
100
110
120
130
140
150
160
170
r

g

b

r+g+b==765?0:c

---)
**scanLineTreatment
スキャン画像のコントラストを調整して線を「アニメ塗り」に特化させるフィルタ
紙の下地域値（ctl(0)）よりも暗い部分を反転した画像と原画像を差合成して背景(用紙)の階調を排除して
残ったデータを指定値で0-255にスケーリングしている。
---(
%RGB-1.0
240
127
10
10
10
10
10
10
i<ctl(0) ? put(scl(255-c,0,255,ctl(0),255),0):put(c,0),\rscl(255
-abs(c-get(0)),ctl(1),225,0,255)\r

i<ctl(0) ? put(scl(255-c,0,255,ctl(0),255),1):put(c,1),\rscl(255
-abs(c-get(1)),ctl(1),225,0,255)\r

i<ctl(0) ? put(scl(255-c,0,255,ctl(0),255),2):put(c,2),\rscl(255
-abs(c-get(2)),ctl(1),225,0,255)\r

a

---)
**scanLineTreatment_s
スキャン画像調整の事前処理。

色トレスの分離を良好にする為に、指定彩度以下のピクセルを強制的に無彩色にしている。
彩度の判定は、FFが提供しているuv値から判定
スライダは
-ctl(0)	彩度指定値
-ctl(1)	Rチャンネル調整係数
-ctl(2)	Gチャンネル調整係数
-ctl(3)	Ｂチャンネル調整係数
---(
%RGB-1.0
127
123
125
123
140
150
160
170
sqr(u*u+v*v)*(ctl(1)/10)> ctl(0)? c :i

sqr(u*u+v*v)*(ctl(2)/10)> ctl(0)? c :i

sqr(u*u+v*v)*(ctl(3)/10)> ctl(0)? c :i

a

---)
**thinXXX
細線化フィルタの機能ブロックフィルタ

XXXの部分は番号で置換。それぞれが細線化工程の機能ブロックになっている。

RGBモード(8bit/チャンネル)で、黒白二値化されていることが使用条件。

全てのフィルタを順次実行することで、黒ラインの周囲を赤で置換してゆく。
どのフィルタもラストの1ピクセルは削らないので、最低でも1ピクセル太さの線が残る。

黒白の線画にする為には、最後に赤を白に置換する必要が有ります。

通常の細線化処理は、終了条件を与えてループ処理するが、FilterFactoryでは、以下の仕様の為やや特殊な構成になっている。

-ループ処理ができない
-加工後のピクセル値の参照ができない

アクションまたはスクリプトで各フィルタを連続実行する必要が有る。

-thin000	右下ピクセルを削る
-thin001	左上ピクセルを削る
-thin002	右ピクセルを削る
-thin003	左ピクセルを削る
---(
//000 r:
i==0 && ( cnv(1,1,1, 0,0,0, 4,4,4, 1)==3060 ||cnv(1,1,0, 1,0,4, 0,4,4, 1)==3060 ||cnv(1,0,4, 1,0,4, 1,0,4, 1)==3060)? put(255,0) : put(c,0),get(0)
//001 r:
i==0 && ( cnv(4,4,4, 0,0,0, 1,1,1, 1)==3060 ||cnv(4,4,0, 4,0,1, 0,1,1, 1)==3060 ||cnv(4,0,1, 4,0,1, 4,0,1, 1)==3060)? put(255,0) : put(c,0),get(0)//from RightBottom
//002 r:
i==0 && ( cnv(4,0,1, 4,0,1, 4,0,1, 1)==3060 ||cnv(0,1,1, 4,0,1, 4,4,0, 1)==3060 ||cnv(1,1,1, 0,0,0, 4,4,4, 1)==3060)? put(255,0) : put(c,0),get(0)//from RightBottom
//003 r:
i==0 && ( cnv(1,0,4, 1,0,4, 1,0,4, 1)==3060 ||cnv(0,4,4, 1,0,4, 1,1,0, 1)==3060 ||cnv(4,4,4, 0,0,0, 1,1,1, 1)==3060)? put(255,0) : put(c,0),get(0)//from RightBottom
---)

