ColorFilter初探一
8972 ワード
MaskFilterは1つのPaintのalphaチャネルへの変換であり、ColorFilterはRGBチャネルごとに変換を適用する.ColorFilterから派生したすべてのクラスは、変換を実行するときにalphaチャネルを無視します.
Androidには3つのColorFilterが含まれています.
ColorMatrixColorFilterは4を指定できます.×5のColorMatrixを1つのPaintに適用します.ColorMatrixesは、通常、プログラムで画像を処理するために使用され、マトリクス乗算法を使用してリンク変換を実行することをサポートするため、便利です.
LightingColorFilterに1色目のRGBチャネルを乗算し、2色目を加算します.各変換の結果は0~255に制限されます.
PorterDuffColorFilterは、デジタル画像合成の16のPorter-Duffルールのいずれかを使用して、指定された色をペイントに適用することができる.
ColorMatrixColorFilter:
1.PorterDuff.Mode.CLEARの描画はキャンバスにコミットされません.2.PorterDuff.Mode.SRCは、上位ペイント画像3を表示する.PorterDuff.Mode.DSTは、下層描画画像4を表示する.PorterDuff.Mode.SRC_MOVERは正常に描画表示され、上下層に重ね蓋が描画されます.5.PorterDuff.Mode.DST_MOVER上下に表示されます.下の段が上に表示されます.6.PorterDuff.Mode.SRC_INは2つのレイヤーで交差を描画します.上位レベルを表示します.7.PorterDuff.Mode.DST_INは2つのレイヤーで交差を描画します.下位レベルを表示します.8.PorterDuff.Mode.SRC_OUT上段描画非交差部分を取ります.9.PorterDuff.Mode.DST_OUT下に非交差部分を描画します.10.PorterDuff.Mode.SRC_ATOPは、下層の非交差部分と上層の交差部分11をとる.PorterDuff.Mode.DST_ATOPは、上層の非交差部分と下層の交差部分12をとる.PorterDuff.Mode.XORは2つのレイヤーを取って非交差を描画します.2つのレイヤが交差しないように描画します.13.PorterDuff.Mode.DARKENの上下に表示されます.暗くなる.PorterDuff.Mode.LIGHTENの上下に表示されます.変数15.PorterDuff.Mode.MULTIPLYは、2層の描画交差16をとる.PorterDuff.Mode.SCREENの上下に表示されます.
コードは次のとおりです.
Androidには3つのColorFilterが含まれています.
ColorMatrixColorFilterは4を指定できます.×5のColorMatrixを1つのPaintに適用します.ColorMatrixesは、通常、プログラムで画像を処理するために使用され、マトリクス乗算法を使用してリンク変換を実行することをサポートするため、便利です.
LightingColorFilterに1色目のRGBチャネルを乗算し、2色目を加算します.各変換の結果は0~255に制限されます.
PorterDuffColorFilterは、デジタル画像合成の16のPorter-Duffルールのいずれかを使用して、指定された色をペイントに適用することができる.
ColorMatrixColorFilter:
ColorMatrix mColorMatrix = new ColorMatrix(new float[]{
.5f, 0, 0, 0, 0,
0, .5f, 0, 0, 0,
0, 0, .5f, 0, 0,
0, 0, 0, 1, 0,
});
drawable.setColorFilter(new ColorMatrixColorFilter(mColorMatrix));
LightingColorFilter: drawable.setColorFilter(new LightingColorFilter(0xffff0000, 0xff00ff00));
PorterDuffCOlorFilter drawable.setColorFilter(new PorterDuffColorFilter(0xffff0000, PorterDuff.Mode.ADD));
次にPorterDuffColorFilterについて重点的に説明します1.PorterDuff.Mode.CLEARの描画はキャンバスにコミットされません.2.PorterDuff.Mode.SRCは、上位ペイント画像3を表示する.PorterDuff.Mode.DSTは、下層描画画像4を表示する.PorterDuff.Mode.SRC_MOVERは正常に描画表示され、上下層に重ね蓋が描画されます.5.PorterDuff.Mode.DST_MOVER上下に表示されます.下の段が上に表示されます.6.PorterDuff.Mode.SRC_INは2つのレイヤーで交差を描画します.上位レベルを表示します.7.PorterDuff.Mode.DST_INは2つのレイヤーで交差を描画します.下位レベルを表示します.8.PorterDuff.Mode.SRC_OUT上段描画非交差部分を取ります.9.PorterDuff.Mode.DST_OUT下に非交差部分を描画します.10.PorterDuff.Mode.SRC_ATOPは、下層の非交差部分と上層の交差部分11をとる.PorterDuff.Mode.DST_ATOPは、上層の非交差部分と下層の交差部分12をとる.PorterDuff.Mode.XORは2つのレイヤーを取って非交差を描画します.2つのレイヤが交差しないように描画します.13.PorterDuff.Mode.DARKENの上下に表示されます.暗くなる.PorterDuff.Mode.LIGHTENの上下に表示されます.変数15.PorterDuff.Mode.MULTIPLYは、2層の描画交差16をとる.PorterDuff.Mode.SCREENの上下に表示されます.
コードは次のとおりです.
public class Xfermodes extends AppCompatActivity {
private static final Xfermode[] sModes = {
new PorterDuffXfermode(PorterDuff.Mode.CLEAR),/** [0, 0] */
new PorterDuffXfermode(PorterDuff.Mode.SRC),/** [Sa, Sc] */ //
new PorterDuffXfermode(PorterDuff.Mode.DST),/** [Da, Dc] */ //
new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER), /** [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] */ //
new PorterDuffXfermode(PorterDuff.Mode.DST_OVER),/** [Sa + (1 - Sa)*Da, Rc = Dc + (1 - Da)*Sc] */ //
new PorterDuffXfermode(PorterDuff.Mode.DST_IN),/** [Sa * Da, Sc * Da] */ // ,
new PorterDuffXfermode(PorterDuff.Mode.SRC_IN), /** [Sa * Da, Sc * Da] */ // ,
new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT),/** [Sa * (1 - Da), Sc * (1 - Da)] */ // ( )
new PorterDuffXfermode(PorterDuff.Mode.DST_OUT),/** [Da * (1 - Sa), Dc * (1 - Sa)] */ // ( )
new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP),/** [Da, Sc * Da + (1 - Sa) * Dc] */ // ,
new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP), /** [Sa, Sa * Dc + Sc * (1 - Da)] */ // ,
new PorterDuffXfermode(PorterDuff.Mode.XOR),/** [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc] */ //
new PorterDuffXfermode(PorterDuff.Mode.DARKEN),/** [Sa + Da - Sa*Da,Sc*(1 - Da) + Dc*(1 - Sa) + min(Sc, Dc)] */ // ,
new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN), /** [Sa + Da - Sa*Da,Sc*(1 - Da) + Dc*(1 - Sa) + max(Sc, Dc)] */ // ,
new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY),/** [Sa * Da, Sc * Dc] */ //
new PorterDuffXfermode(PorterDuff.Mode.SCREEN), /** [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] */ // ,
new PorterDuffXfermode(PorterDuff.Mode.ADD), /** Saturate(S + D) */ //
new PorterDuffXfermode(PorterDuff.Mode.OVERLAY) /** Saturate(S + D) */ // ,
};
private static final String[] sLabels = {
"Clear", "Src", "Dst", "SrcOver",
"DstOver", "SrcIn", "DstIn", "SrcOut",
"DstOut", "SrcATop", "DstATop", "Xor",
"Darken", "Lighten", "Multiply", "Screen", "ADD", "OVERLAY"
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
static Bitmap makeDst(int w, int h) {
Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bm);
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
p.setColor(0xFFFFCC44);
c.drawOval(new RectF(0, 0, w * 3 / 4, h * 3 / 4), p);
return bm;
}
static Bitmap makeSrc(int w, int h) {
Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bm);
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
p.setColor(0xFF66AAFF);
c.drawRect(w / 3, h / 3, w * 19 / 20, h * 19 / 20, p);
return bm;
}
class SampleView extends View {
private static final int ROW_MAX = 4; // number of samples per row
private Bitmap mSrcB;
private Bitmap mDstB;
private Shader mBG; // background checker-board pattern
private static final int W = 64;
private static final int H = 64;
public SampleView(Context context) {
super(context);
mSrcB = makeSrc(W, H);
mDstB = makeDst(W, H);
// 2*2 Bitmap, ,tips: width*height
/*
extend:
Bitmap.Config.ALPHA_8 Alpha 8
Bitmap.Config.ARGB_4444 4 4 16
Bitmap.Config.ARGB_8888 4 8 32
Bitmap.Config.RGB_565 R 5 ,G 6 ,B 5 16
,
*/
Bitmap bm = Bitmap.createBitmap(new int[]{0xFFFFFFFF, 0xFFCCCCCC,
0xFFCCCCCC, 0xFFFFFFFF}, 2, 2,
Bitmap.Config.RGB_565);
// , x、y
mBG = new BitmapShader(bm,
Shader.TileMode.REPEAT,
Shader.TileMode.REPEAT);
Matrix m = new Matrix();
// , 6
m.setScale(6, 6);
mBG.setLocalMatrix(m);// BitmapShader
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.GREEN);
Paint labelP = new Paint(Paint.ANTI_ALIAS_FLAG);//
labelP.setTextAlign(Paint.Align.CENTER);
Paint paint = new Paint();
paint.setFilterBitmap(false);// 。
canvas.translate(15, 35);
int x = 0;
int y = 0;
for (int i = 0; i < sModes.length; i++) {
paint.setStyle(Paint.Style.STROKE);
paint.setShader(null);//
canvas.drawRect(x - 0.5f, y - 0.5f,
x + W + 0.5f, y + H + 0.5f, paint);
//draw the checker-board pattern
paint.setStyle(Paint.Style.FILL);
paint.setShader(mBG);
canvas.drawRect(x, y, x + W, y + H, paint);
// ,
int sc = canvas.saveLayer(x, y, x + W, y + H, null,
Canvas.MATRIX_SAVE_FLAG |
Canvas.CLIP_SAVE_FLAG |
Canvas.HAS_ALPHA_LAYER_SAVE_FLAG |
Canvas.FULL_COLOR_LAYER_SAVE_FLAG |
Canvas.CLIP_TO_LAYER_SAVE_FLAG);
canvas.translate(x, y);
canvas.drawBitmap(mDstB, 0, 0, paint);
paint.setXfermode(sModes[i]);
canvas.drawBitmap(mSrcB, 0, 0, paint);
paint.setXfermode(null);
canvas.restoreToCount(sc);
//
canvas.drawText(sLabels[i],
x + W / 2, y - labelP.getTextSize() / 2, labelP);
x += W + 10;
// wrap around when we've drawn enough for one row
if ((i % ROW_MAX) == ROW_MAX - 1) {
x = 0;
y += H + 30;
}
}
}
}
}
以上がAPIDemoのコードであり、カスタムViewは使用されない場合が多いiv = (ImageView) findViewById(R.id.iv);
iv.getDrawable().setColorFilter(new PorterDuffColorFilter(0xffff0000, PorterDuff.Mode.ADD));
API 21以上で使用可能iv.getDrawable().setTint(0xffff0000);
iv.getDrawable().setTintMode(PorterDuff.Mode.MULTIPLY);