本篇文章主要记录动画以及图像混合模式
Android图像混合模式探究
图像混合模式在编写自定义View的过程中是比较常用的,通过图像混合模式可以实现很多非常炫酷的界面效果,能极大的提升用户体验。
复制代码
一、Xfermode图像混合模式
图像混合模式定义的是,当两个图像合成时,图像最终的展示方式。在Androd中,有相应的API接口来支持图像混合模式,即Xfermode。
通过查看Xfermode的API文档发现,其有三个子类AvoidXfermode, PixelXorXfermode和PorterDuffXfermode,由于AvoidXfermode, PixelXorXfermode都已经被标注为过时了,所以这次主要研究的是PorterDuffXfermode。在用Android中的Canvas进行绘图时,可以通过使用PorterDuffXfermode将所绘制的图形的像素与Canvas中对应位置的像素按照一定规则进行混合,形成新的像素值,从而更新Canvas中最终的像素颜色值,这样会创建很多有趣的效果.
二、PorterDuffXfermode讲解
图形混合的概念是由Tomas Proter和Tom Duff两位大神定义的,而PorterDuffXfermode的名字就是这俩人的人名组合PorterDuff。其定义了很多的混合模式,如下图所示:
这张图片从一定程度上形象地说明了图形混合的作用,两个图形一圆一方通过一定的计算产生不同的组合效果,具体如下:
CLEAR清除图像
SRC只显示源图像
DST只显示目标图像
SRC_OVER将源图像放在目标图像上方
DST_OVER将目标图像放在源图像上方
SRC_IN只在源图像和目标图像相交的地方绘制【源图像】
DST_IN只在源图像和目标图像相交的地方绘制【目标图像】,绘制效果受到源图像对应地方透明度影响
SRC_OUT只在源图像和目标图像不相交的地方绘制【源图像】,相交的地方根据目标图像的对应地方的alpha进行过滤,目标图像完全不透明则完全过滤,完全透明则不过滤
DST_OUT只在源图像和目标图像不相交的地方绘制【目标图像】,在相交的地方根据源图像的alpha进行过滤,源图像完全不透明则完全过滤,完全透明则不过滤
SRC_ATOP在源图像和目标图像相交的地方绘制【源图像】,在不相交的地方绘制【目标图像】,相交处的效果受到源图像和目标图像alpha的影响
DST_ATOP在源图像和目标图像相交的地方绘制【目标图像】,在不相交的地方绘制【源图像】,相交处的效果受到源图像和目标图像alpha的影响
XOR在源图像和目标图像相交的地方之外绘制它们,在相交的地方受到对应alpha和色值影响,如果完全不透明则相交处完全不绘制
DARKEN变暗,较深的颜色覆盖较浅的颜色,若两者深浅程度相同则混合
LIGHTEN变亮,与DARKEN相反,DARKEN和LIGHTEN生成的图像结果与Android对颜色值深浅的定义有关
MULTIPLY正片叠底,源图像素颜色值乘以目标图像素颜色值除以255得到混合后图像像素颜色值
SCREEN滤色,色调均和,保留两个图层中较白的部分,较暗的部分被遮盖
三、图像混合模式的使用
通过PorterDuffXfermode可以实现很多酷炫的界面效果,举例如下:
应用1. 圆形图片
效果如下:
int sc = canvas.saveLayer(0, 0, getWidth(), getHeight(), mPaint, Canvas.ALL_SAVE_FLAG);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.icon512);
int bitmapWidht = bitmap.getWidth();
int bitmapHeight = bitmap.getHeight();
canvas.drawOval(new RectF(0,0,bitmapWidht,bitmapHeight), mPaint);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap,0,0,mPaint);
mPaint.setXfermode(null);
canvas.restoreToCount(sc);
复制代码
实现思路:
首先先画一个圆形
使用SRC_IN混合模式
画图片,这样就换显示图片和圆形重合的图片部分了,实现了圆形图片的效果
应用2.图片的反色处理
效果如下:
原图
反色之后:
int sc = canvas.saveLayer(0, 0, getWidth(), getHeight(), mPaint, Canvas.ALL_SAVE_FLAG);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.tab_icon_home_default);
int bitmapWidht = bitmap.getWidth();
int bitmapHeight = bitmap.getHeight();
Matrix matrix = new Matrix();
matrix.setScale(3, 3);
canvas.drawBitmap(bitmap,matrix, mPaint);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
mPaint.setColor(Color.RED);
canvas.drawRect(new RectF(0,0,bitmapWidht*3,bitmapHeight*3), mPaint);
mPaint.setXfermode(null);
canvas.restoreToCount(sc);
复制代码
实现思路:
首先先画出原图
使用SRC_IN混合模式,画红色的矩形与图片混合
红色矩形与图片重叠的部分,会显示矩形部分,因此展示出来的效果就是图片变成了红色
四、总结
通过上面的介绍可以看出,图形混合模式在日常的开发中是非常有用的,通过PorterDuffXfermode的不同模式的设置,可以实现不同的效果,提升我们的应用的视觉体验。