PorterDuff及Xfermode详解
2015-09-13 22:18
375 查看
Xfermode有三个子类 :
AvoidXfermode 指定了一个颜色和容差,强制Paint避免在它上面绘图(或者只在它上面绘图)。PixelXorXfermode 当覆盖已有的颜色时,应用一个简单的像素异或操作。
PorterDuffXfermode 这是一个非常强大的转换模式,使用它,可以使用图像合成的16条Porter-Duff规则的任意一条来控制Paint如何与已有的Canvas图像进行交互。
要应用转换模式,可以使用setXferMode方法,如下所示:
[java] view
plaincopy
AvoidXfermode avoid = new AvoidXfermode(Color.BLUE, 10, AvoidXfermode.Mode. ***OID); borderPen.setXfermode(avoid);
PorterDuff的使用:
参照android apidemo中com.example.android.apis.graphics下的Xfermodes。这里列出已注释的代码:public class Xfermodes extends GraphicsActivity { // create a bitmap with a circle, used for the "dst" image 创建一个圆形的bitmap,用来做dst图像 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; } // create a bitmap with a rect, used for the "src" image 创建一个矩形bitmap,用来做src图像 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; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new SampleView(this)); } private static class SampleView extends View { private static final int W = 64; private static final int H = 64; 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 Xfermode[] sModes = { new PorterDuffXfermode(PorterDuff.Mode.CLEAR), //所绘制不会提交到画布上。 new PorterDuffXfermode(PorterDuff.Mode.SRC), //显示上层绘制图片 new PorterDuffXfermode(PorterDuff.Mode.DST), //显示下层绘制图片 new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER), //正常绘制显示,上下层绘制叠盖。 new PorterDuffXfermode(PorterDuff.Mode.DST_OVER), //上下层都显示。下层居上显示。 new PorterDuffXfermode(PorterDuff.Mode.SRC_IN), //取两层绘制交集。显示上层。 new PorterDuffXfermode(PorterDuff.Mode.DST_IN), //取两层绘制交集。显示下层。 new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT), //取上层绘制非交集部分。 new PorterDuffXfermode(PorterDuff.Mode.DST_OUT), //取下层绘制非交集部分。 new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP), //取下层非交集部分与上层交集部分 new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP), //取上层非交集部分与下层交集部分 new PorterDuffXfermode(PorterDuff.Mode.XOR), //异或:去除两图层交集部分 new PorterDuffXfermode(PorterDuff.Mode.DARKEN), //取两图层全部区域,交集部分颜色加深 new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN), //取两图层全部,点亮交集部分颜色 new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY), //取两图层交集部分叠加后颜色 new PorterDuffXfermode(PorterDuff.Mode.SCREEN) //取两图层全部区域,交集部分变为透明色 }; private static final String[] sLabels = { "Clear", "Src", "Dst", "SrcOver", "DstOver", "SrcIn", "DstIn", "SrcOut", "DstOut", "SrcATop", "DstATop", "Xor", "Darken", "Lighten", "Multiply", "Screen" }; public SampleView(Context context) { super(context); mSrcB = makeSrc(W, H); mDstB = makeDst(W, H); // make a ckeckerboard pattern 制造一个棋盘模型 Bitmap bm = Bitmap.createBitmap(new int[] { 0xFFFFFFFF, 0xFFCCCCCC, 0xFFCCCCCC, 0xFFFFFFFF }, 2, 2, Bitmap.Config.RGB_565); mBG = new BitmapShader(bm, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); Matrix m = new Matrix(); m.setScale(6, 6); mBG.setLocalMatrix(m); // 设置变换矩阵 } @Override protected void onDraw(Canvas canvas) { canvas.drawColor(Color.WHITE); //整个sampleview为白色 Paint labelP = new Paint(Paint.ANTI_ALIAS_FLAG); //Paint.Align.CENTER 文本被画在x,y origin的横向的中心 //Paint.Align.Left 文本被画在x,y origin的右边 //Paint.Align.Right 文本被画在x,y origin的左边 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++) { // draw the border 画边框 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); // draw the src/dst example into our offscreen bitmap int sc = canvas.saveLayer(x, y, x + W, y + H, null, Canvas.MATRIX_S***E_FLAG | Canvas.CLIP_S***E_FLAG | Canvas.HAS_ALPHA_LAYER_S***E_FLAG | Canvas.FULL_COLOR_LAYER_S***E_FLAG | Canvas.CLIP_TO_LAYER_S***E_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); // draw the label 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; } } } } }
效果图:
参考资料/article/1875776.html
相关文章推荐
- JavaScript的垃圾回收机制
- 《剑指offer》删除链表中重复的结点
- JavaScript的垃圾回收机制
- Jquery EasyUI的添加,修改,删除,查询等基本操作介绍
- js节点操作
- Javascript高级程序设计第十四章(表单)
- JQueryEasyUI datagrid框架的基本使用
- STL之set_union、set_intersection、set_difference、set_symmetric_difference
- Javascript中没有块级作用域(模仿)
- Javascript中没有块级作用域(模仿)
- HTML5 画布
- HTML5 鼠标拖拽以及web存储
- Effective Java 学习 第二条 使用构建器
- JS BOM(浏览器对象)
- JavaScript设计模式——单体模式
- 正确理解javascript当中的面向对象
- jQuery与原生js的函数对比
- jQuery与原生js的函数对比
- [前端] nodejs之express框架和ejs模板引擎的入门
- js 杂碎