Android Paint PorterDuffXfermode
Xfermode
还有一个子类 PorterDuffXfermode
PorterDuffXfermode(PorterDuff.Mode mode)
参数 | 说明 |
---|---|
mode | PorterDuff.Mode 图片混排模式 |
PorterDuff.Mode
PorterDuff.Mode
可以简单的理解为两个图层按照不同模式,可以组合成不同的结果显示出来
Android 提供了 18 种图片混排模式,这些混排模式会用到两个图层:先绘制的图是 目标图(DST) ,后绘制的图是 源图(SRC)
范例
我们写一个范例来演示各种模式
-
创建一个 空的 Android 项目
cn.twle.android.PorterDuffMode
-
自定义一个 View 类
XfermodeView.java
获取了屏幕宽高,然后画了一个矩形一个圆形,计算了一下它们的位置,然后设置下图层,接着设下下画笔 setXfermode,最后绘制到 canvas 上
package cn.twle.android.porterduffmode; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.RectF; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Log; import android.view.View; import android.view.WindowManager; public class XfermodeView extends View { private Context context; //屏幕宽高 private int screenW; //绘制的图片宽高 private int width = 200; private int height = 200; //上层SRC的Bitmap和下层Dst的Bitmap private Bitmap srcBitmap, dstBitmap; public XfermodeView(Context context) { this(context, null); } public XfermodeView(Context context, AttributeSet attrs) { super(context, attrs); this.context = context; WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics dm = new DisplayMetrics(); manager.getDefaultDisplay().getMetrics(dm); screenW = dm.widthPixels; //实例化两个Bitmap srcBitmap = makeSrc(width, height); dstBitmap = makeDst(width, height); } public XfermodeView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public void onMeasure(int width,int height ) { WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics dm = new DisplayMetrics(); manager.getDefaultDisplay().getMetrics(dm); screenW = dm.widthPixels; setMeasuredDimension(screenW,8000); } //定义一个绘制圆形 Bitmap 的方法 private 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(0xFFE54261); c.drawOval(new RectF(0, 0, w * 3 / 4, h * 3 / 4), p); return bm; } //定义一个绘制矩形的 Bitmap 的方法 private 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(0xFF3097F3); c.drawRect(w / 3, h / 3, w * 19 / 20, h * 19 / 20, p); return bm; } @Override protected void onDraw(Canvas canvas) { Paint paint = new Paint(); paint.setFilterBitmap(false); paint.setStyle(Paint.Style.FILL); paint.setTextSize(48.0f); for ( PorterDuff.Mode mode : PorterDuff.Mode.class.getEnumConstants()) { Log.d("modes",mode.name()); canvas.drawText(mode.name(), 10, 50, paint); canvas.drawBitmap(srcBitmap, (screenW / 3 - width) / 2, 100, paint); canvas.drawBitmap(dstBitmap, (screenW / 3 - width) / 2 + screenW / 3, 100, paint); int sc = canvas.saveLayer(0, 0, screenW, 300, null, Canvas.ALL_SAVE_FLAG); canvas.drawBitmap(dstBitmap, (screenW / 3 - width) / 2 + screenW / 3 * 2, 100, paint); //绘制 //设置Paint的Xfermode paint.setXfermode(new PorterDuffXfermode(mode)); canvas.drawBitmap(srcBitmap, (screenW / 3 - width) / 2 + screenW / 3 * 2, 100, paint); paint.setXfermode(null); // 还原画布 canvas.restoreToCount(sc); canvas.translate(0, 400); } } }
-
修改
MainActivity.java
package cn.twle.android.porterduffmode; import android.graphics.PorterDuff; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } }
如果需要查看不同的模式,只要 XfermodeView
下面这条语句即可
private PorterDuff.Mode PD_MODE = PorterDuff.Mode.ADD;
PorterDuff.Mode.ADD
饱和度叠加
PorterDuff.Mode.CLEAR:
所绘制不会提交到画布上
PorterDuff.Mode.DARKEN
取两图层全部区域,交集部分颜色加深
PorterDuff.Mode.DST
只保留目标图的 alpha 和 color,所以绘制出来只有目标图
PorterDuff.Mode.DST_ATOP:
源图和目标图相交处绘制目标图,不相交的地方绘制源图
PorterDuff.Mode.DST_IN
两者相交的地方绘制目标图,绘制的效果会受到原图处的透明度影响
PorterDuff.Mode.DST_OUT
在不相交的地方绘制目标图
PorterDuff.Mode.DST_OVER
目标图绘制在上方
PorterDuff.Mode.LIGHTEN
取两图层全部区域,点亮交集部分颜色
PorterDuff.Mode.MULTIPLY
取两图层交集部分叠加后颜色
PorterDuff.Mode.OVERLAY
叠加
PorterDuff.Mode.SCREEN
取两图层全部区域,交集部分变为透明色
PorterDuff.Mode.SRC
只保留源图像的 alpha 和 color,所以绘制出来只有源图
PorterDuff.Mode.SRC_ATOP
源图和目标图相交处绘制源图,不相交的地方绘制目标图
PorterDuff.Mode.SRC_IN
两者相交的地方绘制源图
PorterDuff.Mode.SRC_OUT
不相交的地方绘制源图
PorterDuff.Mode.SRC_OVER
把源图绘制在上方
PorterDuff.Mode.XOR
不相交的地方按原样绘制源图和目标图