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++の勉強部屋」(目次)へ