2017. 9. 4.
石立 喬

Visual C#とWin2DによるUWPでの画像処理(4)

――― CompositeEffectクラスのModeプロパティを色々と変えて画像を合成する ―――

 Win2Dの画像処理用クラスには、複数の画像を一つにまとめるCompositeEffectクラスとBlendEffectクラスがある。前者は合成(部分的にA画像かB画像かを選択する)であり、後者は混合(A画像とB画像の両者をある比率で足し合わせる)である。ここでは、そのうち、CompositeEffectクラスについて、Modeプロパティを変えて、いろいろな機能を確認した。

CompositeEffectクラスによる画像合成
 使用するCompositeEffectクラスは、Destinationと呼ぶ貼り付け目標画像に対して、Sourceと呼ぶ貼り付け用画像を使用する。主なプロパティは、
   Mode ---------- CanvasComposite列挙子で、SourceOver, DestinationOverその他多数ある
   Sources -------- IList<IGraphicsEffectSource>型
であり、まずModeで実行する処理の種類を設定し、
   Sources.Add(Destination)
   Sources.Add(Dource)
により各画像を設定する。この順序が重要で、Destinationが先でなくてはいけない。
 ここでは、Destination画像のAlpha(不透明度)は1(不透明)に固定し、Source画像については、SA(Source Alpha) = 0の場合とSA = 1の場合を比較した。

CanvasComposite列挙子メンバーの動作
 多くは、Porter-Duff合成代数学(compositing algebra)と呼ばれるオペレータを使用しており、その動作は、下表および図1の通りである。本稿で使用する画像の場合、Destination画像はDA = 1(不透明)としてあるので、Destination画像の全域がDestinationとなる。一方、Source画像には、SA = 0(白部分が透明化)とSA = 1(不透明)の二種類があり、SA = 0の場合は、白部分以外の赤文字のみがSourceとなり、SA = 1の場合はSource画像全域がSourceとなる。




図1 CanvasComposite列挙子各モードの図解


 上記メンバーの他に、Add、Copy、BoundedCopy、MaskInvertがあるが、Addは混合に属すべき動作をし、MaskInvertは画像の反転なので、少し趣旨が違う。CopyとBoundedCopyは合成でも混合でもない。

プログラム
 プログラムの具体例は、CanvasCompisite列挙子の一番最初であるSourceOverについて示す。図2は、すでに以前の稿でもおなじみのグローバルクラスの宣言、タイトルの設定とCreateResourcesの呼び出しである。図3は、Destinatio画像、SA = 0のSource画像、SA = 1のSource画像の三つの原画像を読み込み、それぞれに対応して、二つのCompositeEffectクラスを設定している。
 図4は、Destination画像、Source画像(SA = 1画像のみ、表示的には、SA = 0も同じ)、SourceOverモードでの二つの処理結果結果を、表示するCanvas_Drawのイベントハンドラーである。


図2 グローバルクラスの宣言、タイトルの設定とCreateResourcesの呼び出し



図3 三つの原画像を読み込み、二つのCompositeEffectクラスを設定する



図4 SourceOverモードでの結果を、原画像とともに表示する


得られた結果
 CanvasComposite列挙子の値の小さい順に結果を紹介する。DAはDestination画像のAlpha(不透明度)、SAはSource画像のAlphaを意味する。
SourceOver ------ Sourceが上にくる。SA = 0の時はSourceの下にDestinationが透けて見える。SA = 1ではSourceのみ(図5参照)
DestinationOver --- Destinationが上にくる。DestinationはDA = 1で不透明なので、SA = 0、SA = 1共に、Destinationのみ(図省略)
SourceIn -------- DestinationとSourceが重なる部分にSourceのみを表示するので、Sourceが出力される(図省略)
DestinationIn ----- 重なる部分にDestinationのみを表示する、SA = 0だとSourceの文字部分にDestinationの一部が見える(図6参照)
SourceOut ------- Destinationと重ならない部分のSourceを表示する。DA = 1の場合には、何も出力されない(図省略)
DestinationOut ---- Sourceと重ならない部分のDestinationを表示する。SA = 0だと、白抜きの文字がDestination上に現れる(図7参照)
SourceAtop ------- SourceOverモードと実質的に同じになる(図8参照)
DestinationAtop --- DestinationInモードと実質的に同じ(図8参照)
Xor ------------- DestinatioとSourceの重なる部分を白にする(図10参照)
Add ------------- DestinationとSourceの加算(図11参照)
MaskInvert ------- SA = 1の場合には、Destinationを反転させて、Sourceと掛け合わせる(図12参照)


図5 SourceOverの結果、Destinationの有無にかかわらず、上にSourceが載る



図6 DestinationInモード、両画像の重なり部分にDestinationが表示される



図7 DestinationOutモード、両画像の重なり部分以外にDestinationが表示される



図8 SourceAtopモード、Destinationのある所にSourceが載る、実質的にSourceOutと同じ



図9 DestinationAtopモード、Sourceのある所にDestinationが載る



図10 Xorモード、両画像が存在する部分は「白」になる



図11 Addモード、両画像が加算され、赤文字の彩度が下がった



図12 MaskInvertモード、Destinationが反転され、Sourceと積をとる


Xorモードによる型抜き加工への応用例
 図10に示す通り、Xorモードを使うと、SA = 0のSource画像に透明以外の部分があるとDestination画像に白で表示される。これを応用したのが図13の結果である。プログラムの説明は省略する。DestinationOutモードでも同様の結果になる筈である。


図13 Xorモードでハート型に加工した


参考文献
 Thomas Porter and Tom Duff, "Compositing Digital Images", Computer Graphics, 18, 3, pp253 - 259, July, 1984








「Visual C++の勉強部屋」(目次)へ