欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

绘图进阶(二)

程序员文章站 2024-03-22 21:48:22
...

BlurmaskFliter发光效果与图片阴影

引入:

  • 有了之前的阴影基础可以很快的上手发光部分,但是有以下几点特点需要先了解:
  • 发光效果也是用高斯模糊算法,只会像阴影一样影响边缘,内部图像不受影响
  • 无法指定特定的发光颜色,采用边缘模糊效果进行模糊发光,边缘是什么颜色,发光是什么颜色

概述:

1.setMskFilter()函数的使用(注意使用前关闭硬件加速):

//MaskFilter没有具体实现,是通过派生子类来实现具体的不同的功能,他的两个派生类:BlurMaskFilter和EmbossMaskFilter。其中,BlurFilter可以实现发光效果,而EmbossMaskFilter可以用于实现浮雕效果
public MaskFilter setMaskFilter(MaskFilter maskFilter);

2.BlurMaskFilter函数:

//radius:用来定义模糊半径,同样采用高斯模糊算法
//Blur style:发光样式,Blur.INNER(内发光), Blur.SOLID(外发光),Blur.NORMAL(内外发光),Blur.OUTER(仅显示发光效果)
public BlurMaskFilter(float radius, Blur style);

eg:四种发光效果的发光圆:

public class BlurMaskFliterView extends View {
    //内发光
    private Paint paintIn;
    //外发光
    private Paint paintSo;
    //内外发光
    private Paint paintNo;
    //仅显示发光效果
    private Paint paintOu;
    public BlurMaskFliterView(Context context, AttributeSet attrs) {
        super(context, attrs);


        setLayerType(LAYER_TYPE_SOFTWARE, null);
        paintIn = new Paint();
        paintIn.setColor(Color.BLACK);
        paintIn.setMaskFilter(new BlurMaskFilter(50, BlurMaskFilter.Blur.INNER));


        paintSo = new Paint();
        paintSo.setColor(Color.BLACK);
        paintSo.setMaskFilter(new BlurMaskFilter(50, BlurMaskFilter.Blur.SOLID));




        paintNo = new Paint();
        paintNo.setColor(Color.BLACK);
        paintNo.setMaskFilter(new BlurMaskFilter(50, BlurMaskFilter.Blur.NORMAL));


        paintOu = new Paint();
        paintOu.setColor(Color.BLACK);
        paintOu.setMaskFilter(new BlurMaskFilter(50, BlurMaskFilter.Blur.OUTER));
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawCircle(200, 200, 100, paintIn);
        canvas.drawCircle(400, 200, 100, paintSo);
        canvas.drawCircle(200, 400, 100, paintNo);
        canvas.drawCircle(400, 400, 100, paintOu);


    }
}

2.BlurStyle发光效果:
绘图进阶(二)

给图片添加纯色阴影:
  • 首先分析一下阴影形成的过程,setShadowLayer()函数的阴影的形成首先是产生一个跟原型一样的灰色副本,然后对这个灰色副本应用BlurMaskFilter,使 其内外发光,最后偏移一段距离,成为阴影。

  • 步骤:

    • 绘制一幅跟图片一样大小的灰色图片
    • 对灰色图片应用BlurMaskFilter使其内外发光
    • 偏移原图形一段距离绘制阴影
  • 绘制图形副本:

    • 因为需要画一张位图所对应的灰色图像,所以需要新建一张一样大小的空白图片,而且新图片的透明度要与原图片保持一致,所以我们要做的使大小一样,alpha值一样
//新建一张空白图片,该图片具有与原图片一样的Alpha值,把新建的Bitmap当作返回值进行返回, 而且具体颜色是在使用canvas.drawBitmap()函数时绘制的paint颜色决定的
public Bitmap extractAlpha();

eg:

public class BitmapShadowTest extends View {
    private Paint paint;
    private Bitmap bitmap;
    private Bitmap alphaBitmap;
    public BitmapShadowTest(Context context, AttributeSet attrs) {
        super(context, attrs);
        setLayerType(LAYER_TYPE_SOFTWARE, null);
        paint = new Paint();
        bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.circle3);
        //新建一个Alpha值相同的副本
        alphaBitmap = bitmap.extractAlpha();
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int width = 200;
        int height = width * alphaBitmap.getWidth()/alphaBitmap.getHeight();
        //绘制灰色阴影
        paint.setColor(Color.GRAY);
        paint.setMaskFilter(new BlurMaskFilter(10,BlurMaskFilter.Blur.NORMAL));
        canvas.drawBitmap(alphaBitmap, null, new Rect(10, 10,  width, height),paint);
        //绘制黑色阴影


        
        //首先将画布左移,这样可以露出阴影的一部分
        canvas.translate(-5,-5);
        //将发光指控,否则画出来的图像也具有内外发光
        paint.setMaskFilter(null);
        //画出原图像
        canvas.drawBitmap(bitmap, null, new Rect(0, 0, width, height), paint);


//        canvas.translate(width, 0);
//        paint.setColor(Color.BLACK);
//        canvas.drawBitmap(alphaBitmap, null, new Rect(10, 10, width, height), paint);


    }
}

绘图进阶(二)

Shader和BitmapShader

  • Shader最早的接触是在Unity中,他被叫做着色器 ,用来给空白图形上色的,通过给shader指定对应的对象、渐变色等来填充图形的,Paint中的用于设置shader的函数:
public ShadersetShader(Shader shader);
  • Shader类是一个基类,其中只有两个函数,setLocalMatrix(Matrix localM)和getLocalMatrix(Matrix localM),用来设置坐标变换矩阵,Shader类其实是一个空类,功能也是有他的派生类来实现的,派生类如下:
BitmapShader的基本用法:
//类似于PS中的印章工具,bitmap用来指定图案,tileX用来指定X轴超出的单张图片大小时所用的重复策略,tileY用来指定当Y轴超出单张图片大小时所使用的重复策略
//TileMode.CLAMP: 用边缘色彩来填充多余空间
//TileMode.REPEAT:重复原图像来填充多余空间
//TileMode.MIRROR:重复使用镜像模式的图像来填充多余空间
public BitmapShader(Bitmap bitmap, TileMode tileX, TileMode tileY);

eg:

public class BitmapShaderView extends View {
    private Paint paint;
    private Bitmap bitmap;
    public BitmapShaderView(Context context, AttributeSet attrs) {
        super(context, attrs);
        paint = new Paint();
        bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.niuniu);
        paint.setShader(new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawRect(0, 0 , getWidth(), getHeight(),paint);
    }
}

绘图进阶(二)