Graphics2D API:Paint之阴影与滤镜

一、关于硬件加速

官方文档

1、简述

GPU:图形处理器,用来加速图形的渲染速度
Andorid中,在API 11(3.0)之后,加入了对GPU加速的支持,在API 14(4.0)之后,硬件加速是默认开启的.

2、问题

因为在API >= 14时硬件加速默认开启,如果你的app全部是原生的组件,是不会有任何问题的,但是我们的应用中一般都会有自定义组件,而自定义组件时有些方法是不支持硬件加速或者支持的版本很高,所以这就会出现问题.

3、自定义组件时一些方法支持硬件加速的版本( 摘自官方文档 )
Graphics2D API:Paint之阴影与滤镜_第1张图片
Graphics2D API:Paint之阴影与滤镜_第2张图片
Graphics2D API:Paint之阴影与滤镜_第3张图片

API代表这些方法在>=这些版本才支持硬件加速,红叉代表不支持

4、硬件加速开启与关闭

硬件加速可以在4个级别来控制

(1)Application级别

......

支持开启、关闭

(2)Activity级别
   

支持开启、关闭

(3)Window级别
getWindow().setFlags(
   WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
  WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

只支持开启

(4)View级别
setLayerType(View.LAYER_TYPE_SOFTWARE, null); 

或者在布局文件中通过layerType属性关闭硬件加速

 android:layerType="software" 

只支持关闭

二、阴影

1、介绍

Paint中有一个专门用来实现阴影效果的方法:

public void setShadowLayer(float radius, float dx, float dy, int shadowColor)

radius:阴影半径,设为0就是取消阴影
dx:阴影x轴偏移距离,大于0向右偏移,小于0向左偏移
dy:阴影y轴偏移距离,大于0向下偏移,小于0向上偏移
color:阴影的颜色(对图片阴影无效)

从上面的硬件加速图片中可以找到这个方法:该方法对绘制文本阴影支持硬件加速,其它的都不支持硬件加速,所以,我们在自定义控件中使用到这个方法时,一般都要关闭硬件加速.

2、使用
    private void gogogo(Canvas canvas) {
        this.setLayerType(LAYER_TYPE_SOFTWARE, null);//取消硬件加速

        mPaint.setColor(Color.BLUE);
        mPaint.setTextSize(66);
        mPaint.setShadowLayer(10, 5, 5, Color.GRAY);//阴影

        canvas.drawText("随风飘扬的Smile", 100, 100, mPaint);
        canvas.drawCircle(200, 200, 50, mPaint);
    }
Graphics2D API:Paint之阴影与滤镜_第4张图片
3、移除阴影

一旦我们定义了阴影层,后面绘制的都会带上阴影,如果想取消阴影,可以使用Paint的下面这个方法:

    public void clearShadowLayer() {
        setShadowLayer(0, 0, 0, 0);
    }
4、TextView及其子类阴影

对于原生的TextView及其子类,都支持通过XML设置阴影


Graphics2D API:Paint之阴影与滤镜_第5张图片
    

这几个属性对照上面setShadowLayer的参数一看就明白了.
当然,通过代码设置也是可以的:

public void setShadowLayer(float radius, float dx, float dy, int color)

三、Alpha滤镜

1、setMaskFilter
public MaskFilter setMaskFilter(MaskFilter maskfilter)

在前一篇Paint之颜色过滤中介绍了画笔Paint如何设置颜色滤镜(setColorFilter),这里setMaskFilter介绍的也是滤镜.

和setColorFilter方法介绍的差不多,setMaskFilter方法需要一个MaskFilter 对象,而MaskFilter类中基本啥都没有,所以这里需要的其实是它的2个子类:

注意:setMaskFilter这个方法也是不支持硬件加速

2、BlurMaskFilter 模糊滤镜
public BlurMaskFilter(float radius, Blur style)

radius:模糊半径
style:模糊样式,可选值:
    BlurMaskFilter.Blur.NORMAL  内外模糊
    BlurMaskFilter.Blur.SOLID  图像边界外产生与Paint颜色一致的阴影效果
    BlurMaskFilter.Blur.OUTER  外部模糊,同时将原图像透明
    BlurMaskFilter.Blur.INNER  内部模糊

来看一下它们的效果:

    private void gogogo(Canvas canvas) {
        this.setLayerType(LAYER_TYPE_SOFTWARE, null);//取消硬件加速
        mPaint.setColor(Color.BLUE);

        mPaint.setMaskFilter(new BlurMaskFilter(66, BlurMaskFilter.Blur.NORMAL));
//        mPaint.setMaskFilter(new BlurMaskFilter(66, BlurMaskFilter.Blur.SOLID));
//        mPaint.setMaskFilter(new BlurMaskFilter(66, BlurMaskFilter.Blur.OUTER));
//        mPaint.setMaskFilter(new BlurMaskFilter(66, BlurMaskFilter.Blur.INNER));
        canvas.drawCircle(200, 200, 100, mPaint);
    }
Graphics2D API:Paint之阴影与滤镜_第6张图片
3、EmbossMaskFilter 浮雕滤镜

EmbossMaskFilter 可以让绘制的图形体现出浮雕的效果.
浮雕效果:模拟光照效果,靠近光的一面显得亮一点,远离光的一面显得暗一点,这样就通过颜色的亮暗营造出浮雕的3D立体效果.

public EmbossMaskFilter(float[] direction, float ambient, float specular, float blurRadius)

direction:一个float类型的数组,表示光线的方向,包含三个值---[x, y, z],是一个空间立体坐标系在三个方向的值,最终形成光照方向
ambient:环境光亮度,取值是0到1,值越接近于0,环境光越暗,值越接近于1,环境光越亮
specular:镜面反射系数
blurRadius:浮雕效果中“凸”起的大小

下面来看一看具体效果:

    private void gogogo(Canvas canvas) {
        this.setLayerType(LAYER_TYPE_SOFTWARE, null);//取消硬件加速
        mPaint.setColor(Color.BLUE);
        mPaint.setTextSize(66);

        EmbossMaskFilter filter = new EmbossMaskFilter(new float[]{1, 1, 3}, 0.4f, 8, 3);//浮雕滤镜
        mPaint.setMaskFilter(filter);
        canvas.drawText("随风飘扬的笑", 100, 100, mPaint);
    }
Graphics2D API:Paint之阴影与滤镜_第7张图片

这个滤镜在实际开发中使用率很低,因为最终效果不是很好控制.

你可能感兴趣的:(Graphics2D API:Paint之阴影与滤镜)