色を減算して透明度の値を抽出する

色を減算して透明度の値を抽出する

画像を半透明にして、フラットな背景色を追加したとします。元の写真、背景色、結果 (混合) はわかっています。ただし、追加された透明度 (アルファ値) は不明であり、画像によって異なります。画像の各ピクセルに対して、追加された透明度値を自動的に計算する方法はありますか? これらの値をコピーして、別の写真に適用できますか?

[ 画像 + 透明度(不明で変化) ] + FlatBackground = Mix(不透明)

= [ 半透明画像 ] + FlatBackground = Mix(不透明)

画像のピクセルに対応する追加された各透明度値をコピーする例:

for pixel(0,0) added 127
for pixel(1,0) added 124
for pixel(0,1) added 124
for pixel(1,1) added 120

しかし、もちろんこれらの値を印刷したいわけではありません。マスクのように使用したいだけです。そうすれば、これらの値を別の画像に適用して、同じ効果を作成できます。

答え1

透明度は元のピクセルに加算されるのではなく、掛け算されて混合ピクセルが作られます。PNG仕様

8 ビットのカラー サンプルが 0..255 の範囲にあり、0..1.0 の範囲に正規化されていると仮定して、画像内の各ピクセルに対して次の操作を実行します。

m = Mix/255
p = Picture/255
a = alpha = Transparency/255

m = (p * a) + (b * (1.0 - a))

「a」を解く

a = (m - b) / (p - b)

元の範囲(例:0..255)に戻します。

Transparency = a * 255

残念ながら、これはすべてのピクセルから透明度 (アルファ) を抽出できないことを意味します。特に、Picture == Background (p - b == 0) の場合、透明度は 0..255 の範囲 (a == 0.0 から 1.0 までの任意の値) になる可能性があります。この式をコード内で使用する場合は、ゼロ除算を防ぐ必要があります。

Picture-Background がゼロ以外の場合、透明度を取得できますが、差 (p - b) が小さい場合はあまり正確ではありません。

関連情報