赞
踩
尊重原创,欢迎转载,转载请注明: FROM GA_studio http://blog.csdn.net/tianjian4592
前面关于paint的方法讲解里,讲到 setXfermode 就截止了,原因有两个:
1. 那篇文章已经太长了,我自己都看不下去了;
2. setXfermode 在paint 里占有至关重要的地位;
基于以上两个原因,我们一起来看看这个方法有何妙用。
首先我们还是来看看关于这个方法的说明:
- /**
- * Set or clear the xfermode object. - 设置或清除xfermode对象;
- * Pass null to clear any previous xfermode. - 传递null以清除任何以前的xfermode。
- * As a convenience, the parameter passed is also returned. - 为方便起见,也返回传递的参数。
- *
- * @return xfermode
- */
- public Xfermode setXfermode(Xfermode xfermode) {
- int xfermodeNative = 0;
- if (xfermode != null)
- xfermodeNative = xfermode.native_instance;
- native_setXfermode(mNativePaint, xfermodeNative);
- mXfermode = xfermode;
- return xfermode;
- }
这个方法传进一个 Xfermode 对象,而打开 Xfermode 发现里面没有提供任何可用的构造函数或方法,ctrl +T 看到它有三个子类:
前两个子类 AvoidXfermode 和 PixelXorXfermode 大家可以看到都已经被划上了斜线,下面就简单提及一下,咱们的重点在 PorterDuffXfermode :
1. AvoidXfermode:
/** This xfermode draws, or doesn't draw, based on the destination's * distance from an op-color. * * There are two modes, and each mode interprets a tolerance value. * * Avoid: In this mode, drawing is allowed only on destination pixels that * are different from the op-color. * Tolerance near 0: avoid any colors even remotely similar to the op-color * Tolerance near 255: avoid only colors nearly identical to the op-color * Tolerance near 0: draw only on colors that are nearly identical to the op-color * Tolerance near 255: draw on any colors even remotely similar to the op-color */ public AvoidXfermode(int opColor, int tolerance, Mode mode) { if (tolerance < 0 || tolerance > 255) { throw new IllegalArgumentException("tolerance must be 0..255"); } native_instance = nativeCreate(opColor, tolerance, mode.nativeInt); }
xfermode 是否绘制,基于目标色和参数 op-color 的差距;
其中有两种模式,分别为 Avoid 和 TARGET:
Avoid模式:只会在目标像素值和 op-color "不一样" 的地方进行绘制;
Target模式:只会在目标像素值和 op-color "一样" 的地方进行绘制;
上面的"一样" 和 "不一样" 我都打上了引号,并不是指严格意义上的一样,而是只要在可容忍范围内就代表一样,这个可容忍范围,就是容差值(tolerance),0 代表最小容差,即得和 op-color 真正意义上一样才 ok ,255 则代表最大容差,只要有一点相近,则ok;
咱们一起来看个小例子:
先在网上找个图案,用PS去掉周围部分,主体改为纯色;
当我们使用PS里的魔棒创立选区的时候,发现一次只选取了其中最相近的一部分,这时候可以看到容差为5,但我们的目的是想把图形周围近似的蓝灰色都选中该怎么办呢?容差这时候就起作用了,改大容差,就相当于调大近似度,这个概念和我们里面的容差值是一样的,希望这样说便于理解,我们看下对比图,调到50 一下就可以选中外层所有蓝灰色:
好,我们现在有了一个纯色的图标,假定我们现在有一个需求,需要在某种操作下将图标变色,类似微信底部的tab图标,未选中时时白色,选中时是绿色,这个时候我们就可以用
AvoidXfermode 进行实现,我们一起看看要怎么做:
1. 给paint 设置要变换的颜色和图层混合模式为 AvoidXfermode;
2. 绘制图标;
3. 再绘制对应色块;
由于是对对应颜色进行替换,所以也就形成了图标变色的效果,一起来看看代码:
public class AvoidXfermodeView extends View { private Paint mBitmapPaint, mAvoidPaint; private int mTotalWidth, mTotalHeight; private Bitmap mBitmap; private int mBitWidth, mBitHeight; private Rect mOriginSrcRect, mOriginDestRect; private Rect mAvoidSrcRect, mAvoidDestRect; private AvoidXfermode mAvoidXfermode; public AvoidXfermodeView(Context context) { super(context); initPaint(); initBitmap(); // 对蓝色相近的颜色进行替换 mAvoidXfermode = new AvoidXfermode(Color.BLUE, 150, Mode.TARGET); } private void initBitmap() { mBitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.bluelogo)).getBitmap(); mBitWidth = mBitmap.getWidth(); mBitHeight = mBitmap.getHeight(); } private void initPaint() { mBitmapPaint = new Paint(); // 去锯齿 mBitmapPaint.setAntiAlias(true); // 防抖动 mBitmapPaint.setDither(true); // 图像过滤 mBitmapPaint.setFilterBitmap(true); // 使用上面属性创建一个新paint mAvoidPaint = new Paint(mBitmapPaint); // 颜色设置为红色 mAvoidPaint.setColor(Color.RED); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 绘制原图 canvas.drawBitmap(mBitmap, mOriginSrcRect, mOriginDestRect, mBitmapPaint); // 绘制用于变色图 canvas.drawBitmap(mBitmap, mAvoidSrcRect, mAvoidDestRect, mAvoidPaint); // 设置图层混合模式 mAvoidPaint.setXfermode(mAvoidXfermode); // 绘制色块进行混合,得到最终效果 canvas.drawRect(mAvoidDestRect, mAvoidPaint); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mTotalWidth = w; mTotalHeight = h; mOriginSrcRect = new Rect(0, 0, mBitWidth, mBitHeight); // 为了让图水平居中 int left = (mTotalWidth - mBitWidth) / 2; mOriginDestRect = new Rect(left, 0, left + mBitWidth, mBitHeight); mAvoidSrc
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。