300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > android半透明图层颜色叠加 Android 图层混合模式PorterDuff.Mode

android半透明图层颜色叠加 Android 图层混合模式PorterDuff.Mode

时间:2020-03-12 08:59:31

相关推荐

android半透明图层颜色叠加 Android 图层混合模式PorterDuff.Mode

Android 图层混合模式 PorterDuff.Mode

PorterDuff.Mode它是将所绘制的图形的像素与Canvas中对应位置的像素按照一定规则进行混合,形成新的像素值,从而更新Canvas中最终的像素颜色值.

PorterDuff.Mode共有18种

Android 中使用 图层混合模式常见的地方有三种:

组合渲染ComposeShader (详见: Android Paint总结)

画笔: Paint.setXfermode()

颜色过滤器: PorterDuffColorFilter

本文主要简单说下第二种 画笔: Paint.setXfermode()

PorterDuff.Mode

每一个图层混合模式代表一种规则,根据每种规则计算混合之后的透明通道值和颜色值

使用图层混合模式有几个需要注意的点:

图层混合模式仅作用于src源图像

意思是:以下面谷歌的demo中的第一个为例使用的模式为PorterDuff.Mode.CLEAR

,源图像src为矩形图 目标图为圆形图dst,PorterDuff.Mode.CLEAR表示清除所有颜色值和透明通道,我们从效果可以看到,目标图dst只有与源图像src相交的地方才会有影响

禁用硬件加速

原因: 在Android api 14之后,图层混合的有些api是不支持硬件加速的,系统的硬件加速是默认开启的,所以在使用图层混合模式之前,禁用掉硬件加速 ,方式如下:

//禁止硬件加速

setLayerType(View.LAYER_TYPE_SOFTWARE, null);

离屏绘制

原因: 在不采用离屏绘制的情况下,控件的背景会影响图层混合模式的计算结果,导致得到期望之外的效果

我们看下使用/不使用 离屏绘制的区别:

使用离屏绘制.gif

不使用离屏绘制.gif

通过使用离屏绘制(离屏缓冲),把要绘制的内容单独绘制在缓冲层,保证Xfermode的使用不会出现错误的结果

离屏绘制有两种使用方式,一般使用第一种方式就足够了:

Canvas.saveLayer() 可以做短时的离屏绘制,在绘制之前保存 ,绘制之后结束,使用方式如下:

int saveId= canvas.saveLayer(0, 0, width, height, Canvas.ALL_SAVE_FLAG);

canvas.translate(x, y);

canvas.drawBitmap(mDstB, 0, 0, paint);//绘制操作

paint.setXfermode(xfermode);//设置xfermode

canvas.drawBitmap(mSrcB, 0, 0, paint);//绘制操作

paint.setXfermode(null); //用完清除

canvas.restoreToCount(saveId);//图层恢复

View.setLayerType() 直接把整个View都绘制在离屏缓冲中,使用如下:

setLayerType(LAYER_TYPE_HARDWARE,paint);//使用GPU缓冲

setLayerType(LAYER_TYPE_SOFTWARE,paint);//使用一个Bitmap缓冲

Xfermodes.png

看下PorterDuff.Mode各种模式以及代表的意思:

//其中Sa全称为Source alpha表示源图的Alpha通道;Sc全称为Source color表示源图的颜色;Da全称为Destination alpha表示目标图的Alpha通道;Dc全称为Destination color表示目标图的颜色,[...,..]前半部分计算的是结果图像的Alpha通道值,“,”后半部分计算的是结果图像的颜色值。

//效果作用于src源图像区域

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),

//取两图层全部区域,交集部分饱和度相加

new PorterDuffXfermode(PorterDuff.Mode.ADD),

//取两图层全部区域,交集部分叠加

new PorterDuffXfermode(PorterDuff.Mode.OVERLAY)

};

小案例:刮刮卡

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。