图形混合模式 PorterDuff Xfermodes
16种图形混合模式示例
首先绘制Dst(黄色的),然后绘制Src(蓝色的)问题来了:为何还会有部分黄色?不应该是把src和dst都清除了吗?
图形混合模式简介
ProterDuff的含义ProterDuff是两个人名的组合:Tomas Proter和 Tom Duff,他们是最早在SIGGRAPH(Special Interest Group for Computer GRAPHICS,计算机图形图像特别兴趣小组)上提出图形混合概念的大神级人物。利用ProterBuff.Mode我们可以完成任意2D图像测操作模式使用简介首先绘制Dst(黄色的),然后绘制Src(蓝色的)1.PorterDuff.Mode.CLEAR 所绘制不会提交到画布上
2.PorterDuff.Mode.SRC 显示上层绘制图片
3.PorterDuff.Mode.DST 显示下层绘制图片
4.PorterDuff.Mode.SRC_OVER 正常绘制显示,上下层绘制叠盖
5.PorterDuff.Mode.DST_OVER 上下层都显示。下层居上显示
6.PorterDuff.Mode.SRC_IN 取两层绘制交集。显示上层
7.PorterDuff.Mode.DST_IN 取两层绘制交集。显示下层
8.PorterDuff.Mode.SRC_OUT 取上层绘制非交集部分9.PorterDuff.Mode.DST_OUT 取下层绘制非交集部分
10.PorterDuff.Mode.SRC_ATOP 取下层非交集部分与上层交集部分
11.PorterDuff.Mode.DST_ATOP 取上层非交集部分与下层交集部分
12.PorterDuff.Mode.XOR 取两层绘制非交集。两层绘制非交集
13.PorterDuff.Mode.DARKEN 上下层都显示。变暗
14.PorterDuff.Mode.LIGHTEN 上下层都显示。变量
15.PorterDuff.Mode.MULTIPLY 取两层绘制交集
16.PorterDuff.Mode.SCREEN 上下层都显示
画出这几种模式的效果
public class XfermodesView extends View {private Context context;/**每个item的大小*/private int itemLength;/**每行的数量*/private static final int ROW_MAX = 4;/**首先绘制的黄色的Bitmap*/private Bitmap mDstBitmap;/**然后绘制的蓝色的Bitmap*/private Bitmap mSrcBitmap;/**灰白相间的背景图渲染器*/private Shader bitmapShader;private Paint textPaint;private Paint bitmapPaint;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 XfermodesView(Context context) {super(context);this.context = context;itemLength = dp2px(70);mSrcBitmap = makeSrcBitmap(itemLength, itemLength);mDstBitmap = makeDstBitmap(itemLength, itemLength);//根据width和height创建空位图,然后用指定的颜色数组colors来从左到右从上至下依次填充颜色Bitmap bitmap = Bitmap.createBitmap(new int[] { 0xFFFFFFFF, 0xFFCCCCCC, 0xFFCCCCCC, 0xFFFFFFFF }, 2, 2, Bitmap.Config.RGB_565);bitmapShader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);Matrix matrix = new Matrix();matrix.setScale(dp2px(2), dp2px(2));//本来背景是一个白像素一个会像素,太密集了,此操作目的是放大背景bitmapShader.setLocalMatrix(matrix);textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);textPaint.setTextAlign(Paint.Align.CENTER);textPaint.setTextSize(dp2px(10));bitmapPaint = new Paint();bitmapPaint.setFilterBitmap(false);}@Overrideprotected void onDraw(Canvas canvas) {canvas.drawColor(Color.WHITE);canvas.translate(dp2px(5), dp2px(20));int x = 0;int y = 0;for (int i = 0; i < sModes.length; i++) {// 画正方形边框bitmapPaint.setStyle(Paint.Style.STROKE);bitmapPaint.setShader(null);//不去渲染canvas.drawRect(x - 0.5f, y - 0.5f, x + itemLength + 0.5f, y + itemLength + 0.5f, bitmapPaint);//+-0.5f只是为了精确//画灰白相间的背景bitmapPaint.setStyle(Paint.Style.FILL);bitmapPaint.setShader(bitmapShader);//用上面指定的渲染器渲染canvas.drawRect(x, y, x + itemLength, y + itemLength, bitmapPaint);// 根据不同的模式画两个图int sc = canvas.saveLayer(x, y, x + itemLength, y + itemLength, null, Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG //1|2|4|8|16| Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.FULL_COLOR_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG);canvas.translate(x, y);// 以下是最核心的三行代码canvas.drawBitmap(mDstBitmap, 0, 0, bitmapPaint);bitmapPaint.setXfermode(sModes[i]);canvas.drawBitmap(mSrcBitmap, 0, 0, bitmapPaint);bitmapPaint.setXfermode(null);canvas.restoreToCount(sc);// 画标题canvas.drawText(sLabels[i], x + itemLength / 2, y - textPaint.getTextSize() / 2, textPaint);x += itemLength + dp2px(5);//画完一行后移到下一行if ((i % ROW_MAX) == ROW_MAX - 1) {x = 0;y += itemLength + dp2px(20);}}}private Bitmap makeDstBitmap(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;}private Bitmap makeSrcBitmap(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;}private int dp2px(float dpValue) {float scale = context.getResources().getDisplayMetrics().density;return (int) (dpValue * scale + 0.5f);}}
图形混合模式 PorterDuff Xfermodes的更多相关文章
- Android Paint Xfermode 学习小结
一.setXfermode(Xfermode xfermode) Xfermode国外有大神称之为过渡模式,这种翻译比较贴切但恐怕不易理解,大家也可以直接称之为图像混合模式,因为所谓的"过渡 ...
- 详解Paint的setXfermode(Xfermode xfermode)
一.setXfermode(Xfermode xfermode) Xfermode国外有大神称之为过渡模式,这种翻译比较贴切但恐怕不易理解,大家也可以直接称之为图像混合模式,因为所谓的“过渡”其实就是 ...
- Android之圆形头像裁切
PS:今天项目测试组发现,百度地图定位的数据坐标位置是正确的,但是显示的数据是错误的.最后查来查去发现,那个商厦在百度地图上根本就没有那条数据,这让我如何显示,当初就推崇使用高德地图定位,上面的数据量 ...
- 【腾讯bugly干货分享】Android自绘动画实现与优化实战——以Tencent OS录音机波形动
前言 本文为腾讯bugly的原创内容,非经过本文作者同意禁止转载,原文地址为:http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=1180 ...
- 转载爱哥自定义View系列--Paint详解
上图是paint中的各种set方法 这些属性大多我们都可以见名知意,很好理解,即便如此,哥还是带大家过一遍逐个剖析其用法,其中会不定穿插各种绘图类比如Canvas.Xfermode.ColorFilt ...
- Android Paint以及ColorFilter等
我们可以通过Paint中大量的setter方法来为画笔设置属性: 这些属性大多我们都可以见名知意,很好理解,即便如此,哥还是带大家过一遍逐个剖析其用法,其中会不定穿插各种绘图类比如Canvas.Xfe ...
- Android 画笔Paint
转自 http://wuxiaolong.me/2016/08/20/Paint/ 了解Android Paint,一篇就够.引用Aige<自定义控件其实很简单>系列博客的话“很多时候你压 ...
- 自己定义控件事实上非常easy1/6
尊重原创转载请注明:From AigeStudio(http://blog.csdn.net/aigestudio)Power by Aige 侵权必究! 炮兵镇楼 上一节我们粗略地讲了下怎样去实现我 ...
- Canvas与Paint的0基础使用
看了非常多android自己定义方面的资料,了解了非常多原理,遇到人家自己定义的东西也可以看得懂,可是.当自己去自己定义的时候.发现脑袋一片空白,所以就先从认识Canvas和Paint開始吧! Can ...
随机推荐
- Java中的HashMap和Hashtable
代码: import java.util.*; public class test{ public static void main(String[] args) { HashMap hm = new ...
- mongo学习整理
mongo做为NOSQL家族中一员,被广泛使用以及应用到生产环境中,有其出色的性能.关系型数据库(RDBMS )在互联网中依然是不可替代的一部分,mongo基于NOSQL的特性,在程序中RDBMS不适 ...
- centos 6.5网卡dhcp不能获得网关
环境:vmware +centos6.5 添加两个虚拟网卡.一个自动获取ip(用于上网-桥接) 一个手动(与主机通信用于ssh-NAT). 因为自已手动改了一下ifcfg-eth0里面的HWADDR ...
- 关于多本小说站的SEO—从”易读中文网”获得的心得体会
从目前国内的网站流量来说,电影站,小说站,游戏站等的流量占总流量的比例还是很高的,许多站长把目光投入到了这几个方面,本文就着重来说对于小说站,尤其是多本小说站的SEO心得体会! 对于小说站来说,只要排 ...
- 下拉列表框Combo Box
Combo Box/Combo Box Ex 组合窗口是由一个输入框和一个列表框组成.创建一个组合窗口可以使用成员函数: BOOL CListBox::Create( LPCTSTR lpszText ...
- 遍历元素绑定事件时作用域是怎么回事啊,为什么要用this关键字,而直接使用元素本身就不行?
如下代码,将this改为rows[i]为啥不起作用了 var rows = document.getElementsByTagName("tr"); for(var i=0;i&l ...
- 解压Taobao手机客户端发现的东西
今天解压了Taobao手机客户端发现了几个.so文件, 其中有两个挺感兴趣的,查了一下,以后去研究下. libBSPatch.so 是用于支持增量更新功能的库文件. libwebp.so 好像是We ...
- 如何禁止KEIL初始化RAM为零& 如何判断是软复位还是上电复位
(1)如何禁止KEIL初始化RAM为零? 1. 在KEIL Noinit 打钩 2. <1> 另须对需要热启动保持的变量用 _at_ 关键字指定某个区域,否则还是没用 <2>或 ...
- Valve开源了Direct3D到OpenGL的转译层,方便开发者迁移游戏到Linux(面向游戏玩家的六款最佳 Linux 发行版)
Valve开源了Direct3D到OpenGL的转译层,方便开发者迁移游戏到Linux:https://github.com/ValveSoftware/ToGL Valve SteamBox主机系统 ...
- 杜教的AAA树
膜膜膜,常数挺小的... #include<iostream> #include<cstdio> #include<cmath> #include<algor ...
