图形绘制中的PorterDuffXfermode
1、概述
在android图形渲染中 会使用到图像混合模式
<span style="font-size:18px;">setXfermode(Xfermode xfermode)</span>
Xfermode有三个子类
AvoidXfermode, PixelXorXfermode,这俩个均已经被淘汰
只剩 【PorterDuffXfermode】,这个模式是由俩个大牛Tomas Proter和Tom Duff名字来命名的,PorterDuffXfermode模式能为android图形渲染做啥呢,先来张经典图片
咋看有点晕,先解释一下
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 : 取两图层全部区域,交集部分变为透明色
后来还新增了俩种模式 ADD和OVERLAY
17.PorterDuff.Mode.ADD 饱和度叠加
18.PorterDuff.Mode.OVERLAY: 直接叠加
2、示例代码、
下面听过俩个例子来熟悉一下使用
首先来定义一个获取屏幕宽和高的工具代码
<span style="font-size:18px;">public class ScreenMeasureUtil {
//同时获取宽高
public static int[] getScreenHW(Activity activity) {
DisplayMetrics metrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
int Height = metrics.heightPixels;
int Width = metrics.widthPixels;
int HW[] = new int[]{Height, Width};
}
}</span>
橡皮擦效果
自定义一个eraser的view,然后在之布局文件中引入这个控件即可 EraserView.java,注释很详细,这里使用了DST_IN模式(使用dst_out效果一样)
<span style="font-size:18px;">public class EraserView extends View {
//屏幕宽高
private int[] screenSize;
private int screenH;
private int screenW;
//PorterDuff Mode
private static final PorterDuff.Mode PD_MODE = PorterDuff.Mode.DST_IN;
private static final int MIN_MOVE_DIS = 5;//最小的移动距离:如果我们手指在屏幕上的移动距离小于此值则不会绘制
private float preTouchX, preTouchY;
//绘图
private Canvas mCanvas; //画布
private Paint mPaint;//画笔
private Path mPath;//路径
//前后背景
private Bitmap fgBitmap, bgBitmap;
public EraserView(Context context, AttributeSet attrs) {
super(context, attrs);
screenSize = ScreenMeasureUtil.getScreenHW((Activity) context);
screenH = screenSize[0];
screenW = screenSize[1];
initViews(context);
}
private void initViews(Context context) {
//实例化路径对象
mPath = new Path();
//实例化画笔开启抗锯齿和抗抖动
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
//画笔风格为描边
mPaint.setStyle(Paint.Style.STROKE);
//笔触类型为圆角
mPaint.setStrokeJoin(Paint.Join.ROUND);
//设置描边
mPaint.setStrokeCap(Paint.Cap.ROUND);
//设置描边宽度
mPaint.setStrokeWidth(20);
//设置混合模式
mPaint.setXfermode(new PorterDuffXfermode(PD_MODE));
//此处采用的是DST_IN模式必须要将画笔透明度设置为0
mPaint.setARGB(128, 255, 0, 0);
//前景图片的bitmap
fgBitmap = Bitmap.createBitmap(screenW, screenH, Bitmap.Config.ARGB_8888);
//填充进画布
mCanvas = new Canvas(fgBitmap);
//绘制画布背景颜色为灰色
mCanvas.drawColor(0xffacacac);
//获取底面背景图片
bgBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.bg_splash);
//缩放bitmap至屏幕大小
bgBitmap = Bitmap.createScaledBitmap(bgBitmap, screenW, screenH, true);
}
@Override
protected void onDraw(Canvas canvas) {
//绘制背景
canvas.drawBitmap(bgBitmap, 0, 0, null);
//绘制前景
canvas.drawBitmap(fgBitmap, 0, 0, null);
mCanvas.drawPath(mPath, mPaint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mPath.reset();
mPath.moveTo(x, y);
preTouchX = x;
preTouchY = y;
break;
case MotionEvent.ACTION_MOVE:
float dx = Math.abs(x - preTouchX);
float dy = Math.abs(y - preTouchY);
if (dx >= MIN_MOVE_DIS || dy >= MIN_MOVE_DIS) {
mPath.quadTo(preTouchX, preTouchY, (x + preTouchX) / 2, (y + preTouchY) / 2);
preTouchX = x;
preTouchY = y;
}
break;
}
//重绘视图
invalidate();
return true;
}
}
</span>
图形绘制中的PorterDuffXfermode的更多相关文章
- style在进行图形绘制前,要设置好绘图的样式
是html5出现的新标签,像所有的dom对象一样它有自己本身的属性.方法和事件,其中就有绘图的方法,js能够调用它来进行绘图 ,最近在研读<html5与css3权威指南>下面对其中最好玩的 ...
- python中的turtle库(图形绘画库)
turtle绘图的基础知识:1. 画布(canvas) 画布就是turtle为我们展开用于绘图区域,我们可以设置它的大小和初始位置. 设置画布大小 turtle.screensize(canvwidt ...
- canvas绘制中的API
canvas绘制Z 先贴代码吧: /** * Created by Administrator on 2016/1/26. */ var i; function draw (id){ var canv ...
- 使用Android绘图技术绘制一个椭圆形,然后通过触摸事件让该椭圆形跟着手指移动
引言:在图形绘制中,控制一个图形(圆形,椭圆形,矩形,三角形)移动时,其实计算的都是该图形的中心点移动.在绘制过程中,首先计算出中心点,然后根据中心点的位置计算重图形的上下左右位置.我们假设图形左边为 ...
- Matplotlib基本使用简介
目录 Matplotlib基本使用简介 1. Matplotlib简介 2. Matplotlib操作简介 Matplotlib基本使用简介 1. Matplotlib简介 Matplotlib是 ...
- IOS - 绘制文字 drawInRect: withFont: not working
在图形绘制中,我们经常会需要绘制文本,但我在给PDF上绘制Text时,始终绘制不上, 使用过: [str drawInRect:cubeRect withAttributes:attrs]; CGCo ...
- canvas基础2--绘制图形
栅格 绘制矩形 不同于SVG,HTML中的元素canvas只支持一种原生的图形绘制:矩形.所有其他的图形的绘制都至少需要生成一条路径.不过,我们拥有众多路径生成的方法让复杂图形的绘制成为了可能. 首先 ...
- HTML5:Canvas-绘制图形
到本文的最后,你将学会如何绘制矩形,三角形,直线,圆弧和曲线,变得熟悉这些基本的形状.绘制物体到Canvas前,需掌握路径,我们看看到底怎么做. 栅格 在我们开始画图之前,我们需要了解一下画布栅格(c ...
- Android图形合成和显示系统---基于高通MSM8k MDP4平台
介绍了Android SurfaceFlinger层次以下的图形合成和显示系统,主要基于高通MSM8k MDP4x平台. 做为Android Display专题.SurfaceFlinger的详细介绍 ...
随机推荐
- Openstack: change endpoint IP addresses after installation
Prerequisites You have a single node DevStack installation using mysql for the database that was wor ...
- Android隐式启动Activity可能存在的坑
转载本专栏文章,请注明出处,尊重原创 .文章博客地址:道龙的博客 本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 本篇文章,对隐式启动Activity再做分析. 有些人可能会说了, ...
- APP自动化框架LazyAndroid使用手册(2)--元素自动抓取
作者:黄书力 概述 前面的一篇博文简要介绍了安卓自动化测试框架LazyAndroid的组成结构和基本功能,本文将详细描述此框架中元素自动抓取工具lazy-uiautomaterviewer的使用方法. ...
- Xcode 中的断言
转自:http://weibo.com/p/100808885591f113cdedc3301794e5e7d7e9f0/home?from=page_100808&mod=TAB#_rnd1 ...
- Swift3的playground中对UI直接测试支持的改变
我们知道在Xcode的playground中不仅可以测试console代码,还可以测试UI代码,甚至我们可以测试SpriteKit中的场景,有兴趣的童鞋可以看我之前写的这一篇blog: Xcode的p ...
- 剑指Offer——“你最大的缺点是什么”回答技巧及范例
剑指Offer--"你最大的缺点是什么"回答技巧及范例 问题分析:认识自己的缺点是一个巨大的优点, 当HR问到你缺点的时候, 你的机会来了, 请快展示你的自知之明吧!你想把优点 ...
- Unity 资源管理插件
之所以写这个插件呢,就是为了方便整理项目中的资源文件,我记得之前好像也用了这么一个插件,但是也没去找,还是自己动手写一个吧,需要什么功能就看自己的需求. 在项目的过程中呢,已经写了一个插件来管理材质, ...
- thinkpad彻底消除"触摸键盘"图标
输入“服务”,进入“查看本地服务”,找到“Touch Keyboard and Handwriting Panel Service”, 将其启动类型改为“禁用”,这样的话重启电脑之后也不会自动启动这触 ...
- 21 ViewPager RadioGroup
结构 MainActivity.java package com.qf.day21_viewpagerfragmentrg_demo4; import java.util.ArrayList; imp ...
- java中抽象类的定义和使用
java虽然比较简单,但是细节的知识点还是很多的,现在,介绍一下抽象类的定义和实现基础. 指的是在类中定义方法,而不去实现它,而在它的子类中去具体实现,继承抽象类的子类必须实现父类的抽象方法,除非子类 ...