Color Modes

FX 特殊効果画像演算子

FX 特殊効果画像演算子FX 式の構造

FX 特殊効果画像演算子は、画像の各ピクセルチャンネルに数式を適用します。 FX 式言語は、画像を操作するための強力で柔軟な方法を提供し、画像に対して幅広い操作と変換を実行できます。 FXを使用して、

  • キャンバス、グラデーション、数学的カラーマップを作成する
  • 画像とチャンネル間でカラー値を移動する
  • 画像の平行移動、反転、鏡像化、回転、拡大縮小、せん断、および一般的な歪みを行う
  • 複数の画像をマージまたは合成する
  • 隣接するピクセルを畳み込みまたはマージする
  • 画像メトリックまたは「フィンガープリント」を生成する

この演算子は、画像のすべてのピクセルと各ピクセルのすべてのチャンネルをループし、式の結果を含む新しい画像を返します。式は画像シーケンス内の任意の画像を参照できますが、式に従って適切に更新された最初の画像のコピーのみが返されます。

式は単純にすることができます

magick -size 64x64 canvas:black -channel blue -fx "1/2" fx_navy.png

ここでは、黒を紺色の画像に変換します

    black ==> navy

または、式は複雑にすることができます

magick rose: \
  -fx "(1.0/(1.0+exp(10.0*(0.5-u)))-0.006693)*1.0092503" \
  rose-sigmoidal.png

この式は、ソース画像の高コントラストバージョンになります

    rose ==> rose-sigmoidal

式には変数代入を含めることができます。ほとんどの場合、代入により式の複雑さが軽減され、他の方法では不可能な操作が可能になります。たとえば、放射状グラデーションを作成してみましょう

magick -size 70x70 canvas: \
  -fx "Xi=i-w/2; Yj=j-h/2; 1.2*(0.5-hypot(Xi,Yj)/70.0)+0.5" \
  radial-gradient.png

上記のコマンドはこの画像を返します

    radial-gradient

この FX 式は、画像にランダムノイズを追加します

magick photo.jpg -fx 'iso=32; rone=rand(); rtwo=rand(); \
  myn=sqrt(-2*ln(rone))*cos(2*Pi*rtwo); myntwo=sqrt(-2*ln(rtwo))* \
  cos(2*Pi*rone); pnoise=sqrt(p)*myn*sqrt(iso)* \
  channel(4.28,3.86,6.68)/255; max(0,p+pnoise)' noisy.png

この FX スクリプトは、ループを使用してジュリア集合を作成します

magick -size 400x400 xc:gray -fx " \
  Xi=2.4*i/w-1.2; \
  Yj=2.4*j/h-1.2; \
  for (pixel=0.0, (hypot(Xi,Yj) < 2.0) && (pixel < 1.0), \
    delta=Xi^2-Yj^2; \
    Yj=2.0*Xi*Yj+0.2; \
    Xi=delta+0.4; \
    pixel+=0.00390625 \
  ); \
  pixel == 1.0 ? 0.0 : pixel" \
  \( -size 1x1 xc:white xc:red xc:orange xc:yellow xc:green1 xc:cyan xc:blue \
     xc:blueviolet xc:white -reverse +append -filter Cubic -resize 1024x1! \) \
  -clut -rotate -90 julia-set.png
    Julia Fractals

この FX スクリプトは、最初の10個の素数を表示します

magick xc:gray -fx " \
  for (prime=2, prime < 30, composite=0; \
    for (nn=2, nn < (prime/2+1), if ((prime % nn) == 0, composite++, ); nn++); \
      if (composite <= 0, debug(prime), ); prime++)" null:

詳細な例については、FX、特殊効果画像演算子の使用を参照してください。

-fxオプションは、任意の画像シーケンスを、式の結果で更新された最初の画像のクローンに置き換えます。シーケンス内の各画像に式を適用する場合は、代わりに+fxを使用してください。

FX 式はシングルスレッドで解釈されますが、式にdebug()関数が含まれていない限り、マルチスレッドで実行されます。

次のセクションでは、FX 式言語について説明します。

FX 式の構造

FX 式言語

正式な FX 式言語はここで定義されています

数値
整数、浮動小数点数、科学表記法(+/-必須、例:3.81469e-06)、国際単位系数値接尾辞(例:KB、Mib、GBなど)
定数
E(オイラー数)、イプシロン、不透明、ファイ(黄金比)、パイ、QuantumRange、QuantumScale、透明
FX 演算子(優先順位順)
^(べき乗)、単項-、*、/、%(剰余)、+、-、<<、>>、<、<=、>、>=、+=、-=、*=、/=、%=、<<=、>>=、&=、|=、++、--、==、!=、&(ビット単位AND)、|(ビット単位OR)、&&(論理AND)、||(論理OR)、〜(論理NOT)、?:(三項条件)
配列
画像は、その幅と高さによって制限される配列ストレージを提供します(例:p [-1、-1] .r)。画像シーケンスは複数の配列を表します(例:u.p [0,0] .r、v.p [0,0] .r)。ストレージはQuantum値に制限されています。たとえば、Q16ビルドの場合は[0..65535]、HDRI対応ビルドの場合は浮動小数点数です。
数学関数
abs()、acos()、acosh()、airy()、alt()、asin()、asinh()、atan()、atanh()、atan2()、ceil()、clamp()、cos()、cosh()、debug()、drc()、erf()、exp()、floor()、gauss()、gcd()、hypot()、int()、isnan()、j0()、j1()、jinc()、ln()、log()、logtwo()、max()、min()、mod()、not()、pow()、rand()、round()、sign()、sin()、sinc()、sinh()、sqrt()、squish()、tan()、tanh()、trunc()
チャンネル関数
最大5つのピクセルチャンネルを定義する
カラー名
赤、シアン、黒など
カラー関数
srgb()、srgba()、rgb()、rgba()、cmyk()、cmyka()、hsl()、hsla()など
カラー16進値
#ccc、#cbfed0、#b9e1cc00など
記号
u:リストの最初の画像
v:リストの2番目の画像
s:リストの現在の画像(%[fx:]の場合はそうでない場合= u)
t:リスト内の現在の画像(s)のインデックス
n:リスト内の画像の数
i:列オフセット
j:行オフセット
p:使用するピクセル(絶対または現在のピクセルからの相対)
w:この画像の幅
h:この画像の高さ
z:チャンネルの深さ
r:特定または現在のピクセルの赤の値(RGBAから)
g:緑
b:青
a:アルファ
o:不透明度
c:ピクセルのCMYKカラーのシアン値
y:黄
m:マゼンタ
k:黒
all:すべてのチャンネル
this:このチャンネル
intensity:ピクセル強度
hue:ピクセル色相
saturation:ピクセル彩度
lightness:ピクセル明度
luma:ピクセル輝度
page.width:ページ幅
page.height:ページの高さ
page.x:ページxオフセット
page.y:ページyオフセット
printsize.x:x印刷サイズ
printsize.y:y印刷サイズ
resolution.x:x解像度
resolution.y:y解像度
depth:画像の深さ
extent:画像エクステント
minima:画像最小値
maxima:画像最大値
mean:画像平均
median:画像中央値
standard_deviation:画像標準偏差
kurtosis:画像尖度
skewness:画像歪度(チャネル指定子を追加して、そのチャネルの統計を計算します。例:depth.r)
イテレータ
do()、for()、while()
画像属性
s.depth、s.kurtosis、s.maxima、s.mean、s.minima、s.resolution.x、s.resolution.y、s.skewness、s.standard_deviation
ユーザー設定
ユーザー設定としてFx記号を定義します。例:
magick ... -set option:wd1 "%[fx:w/2]" -resize "%[fx:wd1-5]" ...

FX 式

FX式には、以下の任意の組み合わせを含めることができます

x ^ y
べき乗(xy
( ... )
グループ化
x * y
掛け算
x / y
割り算
x % y
剰余
x + y
加算
x - y
減算
x << y
左シフト
x >> y
右シフト
x < y
ブール関係、x < yの場合は値1.0を返し、それ以外の場合は0.0を返します
x <= y
ブール関係、x <= yの場合は値1.0を返し、それ以外の場合は0.0を返します
x > y
ブール関係、x > yの場合は値1.0を返し、それ以外の場合は0.0を返します
x >= y
ブール関係、x >= yの場合は値1.0を返し、それ以外の場合は0.0を返します
x == y
ブール関係、x == yの場合は値1.0を返し、それ以外の場合は0.0を返します
x != y
ブール関係、x != yの場合は値1.0を返し、それ以外の場合は0.0を返します
x & y
ビット単位AND
x | y
ビット単位OR
x && y
論理AND接続詞、x > 0かつy > 0の場合は値1.0を返し、それ以外の場合は0.0を返します
x || y
論理OR接続詞(包含)、x > 0またはy > 0(または両方)の場合は値1.0を返し、それ以外の場合は0.0を返します
~x
論理NOT演算子、not x > 0の場合は値1.0を返し、それ以外の場合は0.0を返します
+x
単項プラス、1.0 *値を返す
-x
単項マイナス、-1.0 *値を返す
条件 ? trueステートメント : falseステートメント
三項条件式、条件!= 0の場合は値trueステートメントを返し、それ以外の場合はfalseステートメントを返します
x = y
代入;単一文字変数は予約されています。代わりに、2文字以上、文字の組み合わせのみを使用してください(例:X1ではなくXi)
x ; y
ステートメントセパレーター
phi
定数(1.618034 ...)
pi
定数(3.14159265359 ...)
e
定数(2.71828 ...)
QuantumRange
定数最大ピクセル値(Q8の場合は255、Q16の場合は65535)
QuantumScale
定数1.0 / QuantumRange
強度
-intensityオプションを考慮した値を持つピクセル強度。
色相
ピクセル色相
彩度
ピクセル彩度
明度
ピクセル明度; 0.5 * max(赤、緑、青)+ 0.5 * min(赤、緑、青)と同等
輝度
ピクセル輝度; 0.212656 *赤+ 0.715158 *緑+ 0.072186 *青と同等
赤、緑、青など
カラー名
#ccc、#cbfed0、#b9e1cc00など
カラー16進値
rgb()、rgba()、cmyk()、cmyka()、hsl()、hsla()
カラー関数
s、t、u、v、n、i、j、w、h、z、r、g、b、a、o、c、y、m、k
記号
abs(x)
絶対値関数
acos(x)
逆余弦関数
acosh(x)
逆双曲線余弦関数
airy(x)
エアリー関数(最大= 1、最小= 0); airy(x)= [jinc(x)] 2 = [2 * j1(pi * x)/(pi * x)] 2
alt(x)
符号交番関数(int(x)が偶数の場合は1.0を返し、int(x)が奇数の場合は-1.0を返します)
asin(x)
逆正弦関数
asinh(x)
逆双曲線正弦関数
atan(x)
逆正接関数
atanh(x)
逆双曲線正接関数
atan2(y,x)
2変数の逆正接関数
ceil(x)
引数以上の最小の整数値
channel(...)
ゼロから5つの引数をサポートします。たとえば、channel(0.1)は最初のチャネルを0.1に設定し、他のチャネルをゼロにします。
clamp(x)
クランプ値
cos(x)
コサイン関数
cosh(x)
双曲線コサイン関数
debug(x)
x を出力します(式のデバッグに役立ちます)
do(statements, condition)
条件が 0 以外である間、反復します
drc(x,y)
ダイナミックレンジ圧縮(ニーカーブ); drc(x,y)=(x)/(y*(x-1)+1); -1<y<1
erf(x)
誤差関数
exp(x)
自然指数関数 (ex)
floor(x)
引数以下の最大の整数値
for(initialize, condition, statements)
条件が 0 以外である間、反復します
gauss(x)
ガウス関数; gauss(x)=exp(-x*x/2)/sqrt(2*pi)
gcd(x,y)
最大公約数
hypot(x,y)
x2+y2 の平方根
if(condition, nonzero-statements, zero-statements)
条件に応じて式を解釈します
int(x)
最大整数関数(x 以下の最大の整数を返します)
isnan(x)
x が NAN の場合 1.0 を返し、そうでない場合 0.0 を返します
j0(x)
0 次の第一種ベッセル関数
j1(x)
1 次の第一種ベッセル関数
jinc(x)
jinc 関数 (最大値=1, 最小値=-0.1323); jinc(x)=2*j1(pi*x)/(pi*x)
ln(x)
自然対数関数
log(x)
10 を底とする対数
logtwo(x)
2 を底とする対数
ln(x)
自然対数
max(x, y)
xy の最大値
min(x, y)
xy の最小値
mod(x, y)
浮動小数点剰余関数
not(x)
x がゼロの場合 1.0 を返し、そうでない場合 0.0 を返します
pow(x,y)
べき乗関数 (xy)
rand()
周期 2 の 128 乗 -1 で、区間 [0.0, 1.0) に均一に分布した値
round()
丸め方向に関係なく、整数値に丸めます
sign(x)
x が 0.0 未満の場合 -1.0 を返し、そうでない場合 1.0 を返します
sin(x)
サイン関数
sinc(x)
sinc 関数 (最大値=1, 最小値=-0.21); sinc(x)=sin(pi*x)/(pi*x)
squish(x)
squish 関数; squish(x)=1.0/(1.0+exp(-x))
sinh(x)
双曲線サイン関数
sqrt(x)
平方根関数
tan(x)
タンジェント関数
tanh(x)
双曲線タンジェント関数
trunc(x)
ゼロ方向に整数に丸めます
while(condition, statements)
条件が 0 以外である間、反復します
image.depth、image.kurtosis、image.maxima、image.mean、image.median、image.minima、image.resolution.x、image.resolution.y、image.skewness、image.standard_deviation
画像属性

式のセマンティクスには、以下のルールが含まれます

  • シンボルは大文字と小文字を区別しません
  • ステートメントごとに三項条件式(例:x ? y : z)は 1 つだけです
  • ステートメントは、代入文または返す最終的な式です
  • 代入はステートメントを開始します。演算子ではありません
  • 1 文字の変数は予約されています。予約済みの組み込み関数への代入は例外をスローします。例:r=3.0; r は *Attempted assignment to non-UserSymbol 'r' at '3.0'* を返します。
  • 単項演算子は二項演算子よりも優先順位が低くなります。つまり、単項マイナス(否定)はべき乗よりも優先順位が低いため、-3^2 は -(3^2) = -9 と解釈されます。意図を明確にするために括弧を使用してください(例:(-3)^2 = 9)。
  • スラッシュ( '/')記号を使用する場合は注意が必要です。1/2x という文字列は (1/2)x と解釈されます。反対の解釈は 1/(2x) と明示的に記述する必要があります。繰り返しますが、括弧を使用すると意味が明確になるため、誤解の可能性がある場合は常に使用する必要があります。
  • -- は変数のデクリメント演算子であるため、負の数を減算するには括弧を使用します。例:-4-(-5)

ソース画像

シンボル u および v は、現在の画像シーケンスのそれぞれ最初と 2 番目の画像を参照します。シーケンス内の特定の画像を参照するには、任意の画像参照(通常は u)にインデックスを追加します。シーケンスの先頭はインデックス 0 です。負のインデックスは末尾からカウントします。たとえば、u[0] はシーケンスの最初の画像、u[2] は 3 番目の画像、u[-1] は最後の画像、u[t] は現在の画像です。現在の画像は s で参照することもできます。シーケンス番号がシーケンスの長さを超えると、カウントはラップアラウンドされます。したがって、3 つの画像シーケンスでは、u[-1]u[2]、および u[5] はすべて同じ(3 番目の)画像を参照します。

例として、最初と 3 番目の画像を平均して画像を形成します(2 番目の(インデックス 1)画像は無視され、単に破棄されます)

magick image1.jpg image2.jpg image3.jpg -fx "(u+u[2])/2" image.jpg

デフォルトでは、prgba などが適用される画像は、画像リストの現在の画像 s です。これは、エスケープシーケンス %[fx:...] で使用される場合を除き、u と同等です。

最初の画像が特別な役割を果たしていることに注意することが重要です。これは、画像シーケンス内で変更される唯一の画像であり、他の画像はデータのためにのみ使用されます。 illustrative な例として、以下を検討してください。-channel red 設定は -fx に緑チャネルのみを変更するように指示します。赤または青チャネルの何も変更されません。結果が対称でない理由を考えることは有益です。

magick logo: -flop logo: -resize "20%" -channel green -fx "(u+v)/2" image.jpg
    logo-sm-flop.png logo-sm.png ==> logo-sm-fx.png

ピクセルへのアクセス

すべての色値は 0.0 から 1.0 の範囲に正規化されます。アルファチャネルの範囲は 0.0(完全に透明)から 1.0(完全に不透明)です。

ピクセルは一度に 1 つずつ処理されますが、p で表されるピクセルインデックスを使用して、画像の別のピクセルを指定できます。例えば、

p[-1].g      green value of pixel to the immediate left of the current pixel
p[-1,-1].r   red value of the pixel diagonally left and up from current pixel

絶対位置を指定するには、ブラケットではなく中括弧を使用します。

p{0,0}.r     red value of the pixel in the upper left corner of the image
p{12,34}.b   blue pixel value at column number 12, row 34 of the image

位置の整数値は参照されるピクセルの色を取得しますが、非整数位置値は現在の -interpolate 設定に従ってブレンドされた色を返します.

画像の境界外の位置は、-virtual-pixel オプション設定によって指示される値を取得します。

現在の画像の赤チャネルを指定するには、u.r を指定します。チャネル修飾子を指定しないと、現在のチャネルが取得されます。出力チャネルを入力チャネルの平均に設定するには、mean.this を使用します。入力チャネルの全体的な平均を設定するには、mean.all を使用します。

式の適用を選択画像チャネル

結果の出力チャネルを指定するには、-channel 設定を使用します。出力チャネルが指定されていない場合、結果は不透明度チャネルを除くすべてのチャネルに設定されます。たとえば、alpha.png の赤チャネルを alpha.pngbeta.png の画像の緑チャネルの平均に置き換えるには、次を使用します

magick alpha.png beta.png -channel red -fx "(u.g+v.g)/2" gamma.png

結果

-fx 演算子は、シーケンスの最初の画像 (u) の各ピクセルの各チャネル(-channel で設定)に対して指定された式を評価します。計算された値は、すべてのピクセルが処理されるまで、その最初の画像のコピー(クローン)に一時的に保存されます。その後、この単一の新しい画像が現在の画像シーケンスの画像リストを置き換えます。そのため、前の例では、更新されたバージョンの alpha.png は、gamma.png として保存される前に、元の画像 alpha.pngbeta.png の両方を置き換えます。

現在の画像 s はシーケンスの最初の画像 (u) に設定され、t はそのインデックス 0 に設定されます。シンボル i および j は処理中の現在のピクセルを参照します.

-format で使用する場合、値エスケープ %[fx:] は現在の画像シーケンスの各画像に対して一度だけ評価されます。シーケンスの各画像が評価されると、s および t は現在の画像とそのインデックスを連続して参照し、i および j はゼロに設定され、現在のチャネルは赤に設定されます(-channel は無視されます)。 例

$ magick canvas:'rgb(25%,50%,75%)' rose: -colorspace gray  \
  -format 'Red channel of NW corner of image #%[fx:t] is %[fx:s]\n' info:
Red channel of NW corner of image #0 is 0.464883
Red channel of NW corner of image #1 is 0.184582

ここでは、画像インデックスを使用して各画像を異なる方法で回転し、画像インデックスで -set を使用してアニメーションの最初の画像に異なる一時停止遅延を設定します

magick rose: -duplicate 29 -virtual-pixel Gray -distort SRT '%[fx:360.0*t/n]' \
  -set delay '%[fx:t == 0 ? 240 : 10]' -loop 0 rose.gif

この例では、RMSE で測定された 2 つの画像の差をテストします。差が 0.1 より大きい場合は 1 を返し、そうでない場合は 0 を返します

magick water.png reference.png -metric RMSE -compare -format "%[fx:%[distortion]>0.1]" info:

カラーエスケープ %[pixel:] または %[hex:] は、画像ごとに、その画像のカラーチャネルごとに一度評価されます(-channel は無視されます)。生成された値は、カラー文字列(名前付きカラーまたは 16 進カラー値)に変換されます。シンボル i および j はゼロに設定され、s および t は連続する現在の画像とインデックスを参照します。