Android で画像を PorterDuff を使って
合成する方法がようやくわかったので
AndroidLibrary@wada811 に BitmapUtils#synthesize(Bitmap, Bitmap, PorterDuff.Mode) を
追加しました。
Porter さんと Duff さんがまとめた(※)
画像合成のルールが
PorterDuff.Mode クラスで指定できます。
(※
Alpha compositing - Wikipedia, the free encyclopedia)
PorterDuffXfermode クラスというものがありますが
Xfermode に PorterDuff.Mode を入れているだけでした。
Xfermode とは Transfer mode という意味です。
PorterDuff.Mode のコメントはわかりにくいですが、
以下のような意味があると思われます。
Sa: ソース画像のアルファ、Sc: ソース画像のカラー
Da: 合成先画像のアルファ、Dc: 合成先画像のカラー
[Ra, Rc]: [結果画像のアルファ, 結果画像のカラー]
public class PorterDuffXfermode extends Xfermode {
/**
* @hide
*/
public final PorterDuff.Mode mode;
/**
* Create an xfermode that uses the specified porter-duff mode.
*
* @param mode The porter-duff mode that is applied
*/
public PorterDuffXfermode(PorterDuff.Mode mode) {
this.mode = mode;
native_instance = nativeCreateXfermode(mode.nativeInt);
}
private static native int nativeCreateXfermode(int mode);
}
/**
* Xfermode is the base class for objects that are called to implement custom
* "transfer-modes" in the drawing pipeline. The static function Create(Modes)
* can be called to return an instance of any of the predefined subclasses as
* specified in the Modes enum. When an Xfermode is assigned to an Paint, then
* objects drawn with that paint have the xfermode applied.
*/
public class Xfermode {
protected void finalize() throws Throwable {
try {
finalizer(native_instance);
} finally {
super.finalize();
}
}
private static native void finalizer(int native_instance);
int native_instance;
}
public class PorterDuff {
// these value must match their native equivalents. See SkPorterDuff.h
public enum Mode {
/** [0, 0] */
CLEAR (0),
/** [Sa, Sc] */
SRC (1),
/** [Da, Dc] */
DST (2),
/** [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] */
SRC_OVER (3),
/** [Sa + (1 - Sa)*Da, Rc = Dc + (1 - Da)*Sc] */
DST_OVER (4),
/** [Sa * Da, Sc * Da] */
SRC_IN (5),
/** [Sa * Da, Sa * Dc] */
DST_IN (6),
/** [Sa * (1 - Da), Sc * (1 - Da)] */
SRC_OUT (7),
/** [Da * (1 - Sa), Dc * (1 - Sa)] */
DST_OUT (8),
/** [Da, Sc * Da + (1 - Sa) * Dc] */
SRC_ATOP (9),
/** [Sa, Sa * Dc + Sc * (1 - Da)] */
DST_ATOP (10),
/** [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc] */
XOR (11),
/** [Sa + Da - Sa*Da,
Sc*(1 - Da) + Dc*(1 - Sa) + min(Sc, Dc)] */
DARKEN (12),
/** [Sa + Da - Sa*Da,
Sc*(1 - Da) + Dc*(1 - Sa) + max(Sc, Dc)] */
LIGHTEN (13),
/** [Sa * Da, Sc * Dc] */
MULTIPLY (14),
/** [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] */
SCREEN (15),
/** Saturate(S + D) */
ADD (16),
OVERLAY (17);
Mode(int nativeInt) {
this.nativeInt = nativeInt;
}
/**
* @hide
*/
public final int nativeInt;
}
}