Paint介绍

Paint介绍


1. Paint.Cap

注意:Cap一般作用于边界处,不作用连接处
BUTT (0),//无线帽
ROUND (1),//圆形线帽
SQUARE (2);//方形线帽

![Cap图片]!
https://img-blog.csdn.net/20170824202318947?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbTBfMzc1OTkzNjM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast


        paint.setColor(Color.RED);
        paint.setStrokeWidth(60);
        paint.setStrokeCap(Paint.Cap.BUTT);
        canvas.drawLine(100, 100, 600, 100, paint);

        paint.setStrokeCap(Paint.Cap.ROUND);
        canvas.drawLine(100, 300, 600, 300, paint);

        paint.setStrokeCap(Paint.Cap.SQUARE);
        canvas.drawLine(100, 500, 600, 500, paint);

2. Paint.Join

MITER   (0),//有尖角的连接
ROUND   (1),//圆弧连接
BEVEL   (2);//直线连接
        paint.setStrokeWidth(60);
        paint.setColor(Color.YELLOW);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeJoin(Paint.Join.MITER);
        canvas.drawRect(new RectF(100,100,300,300),paint);
        paint.setStrokeJoin(Paint.Join.BEVEL);
        canvas.drawRect(400, 100, 600, 300, paint);
        paint.setStrokeJoin(Paint.Join.ROUND);
        canvas.drawRect(100, 400, 300, 600, paint);

第一个是MITER,第二个是BEVEL,第三个是ROUND

3. Paint.Align

        paint.setStrokeWidth(5);
        paint.setTextSize(30);
        paint.setShadowLayer(10,10,10,Color.RED);
        paint.setTextAlign(Paint.Align.LEFT);
        canvas.drawText("Paint.Align.LEFT",400,100,paint);
        paint.setShadowLayer(10,10,10,Color.RED);
        paint.setTextAlign(Paint.Align.CENTER);
        canvas.drawText("Paint.Align.CENTER",400,300,paint);
        paint.setShadowLayer(10,10,10,Color.RED);
        paint.setTextAlign(Paint.Align.RIGHT);
        canvas.drawText("Paint.Align.RIGHT",400,500,paint);
        canvas.drawLine(400,0,400,800,paint);

4. Paint.Style
Paint.Style.FILL:填充内部
Paint.Style.STROKE 描边
Paint.Style.FILL_AND_STROKE :填充内部和描边

  paint.setStrokeWidth(20);
        paint.setStyle(Paint.Style.FILL);
        canvas.drawRect(new RectF(100,100,300,300),paint);
        canvas.drawText("Paint.Style.FILL",350,200,paint);
        paint.setStyle(Paint.Style.STROKE);
        canvas.drawRect(new RectF(100,350,300,550),paint);
        canvas.drawText("Paint.Style.STROKE",350,400,paint);
        paint.setStyle(Paint.Style.FILL_AND_STROKE);
        canvas.drawRect(new RectF(100,600,300,800),paint);

        canvas.drawRect(new RectF(100,350,300,550),paint);
        canvas.drawText("Paint.Style.FILL_AND_STROKE",350,700,paint);

5.Paint.FontMetrics


ascent = ascent线的y坐标 - baseline线的y坐标;//负数

descent = descent线的y坐标 - baseline线的y坐标;//正数

top = top线的y坐标 - baseline线的y坐标;//负数

bottom = bottom线的y坐标 - baseline线的y坐标;//正数

leading = top线的y坐标 - ascent线的y坐标;//负数

  paint.setStrokeWidth(1);
        paint.setTextSize(50);
        Paint.FontMetrics fontMetrics = paint.getFontMetrics();
        float ascent = fontMetrics.ascent +300;
        float descent = fontMetrics.descent+300;
        float top = fontMetrics.top + 300;
        float bottom = fontMetrics.bottom + 300;
        canvas.drawText("abcdefg",300,300,paint);
        paint.setTextSize(20);
        canvas.drawLine(300,ascent,600,ascent,paint);
        canvas.drawText("ascent=top",650,ascent,paint);
        canvas.drawLine(300,descent,600,descent,paint);
        canvas.drawText("descent=bottom",650,descent,paint);
        canvas.drawLine(300,-(bottom-top)/2+bottom,600,-(bottom-top)/2+bottom,paint);//中线
        canvas.drawText("center",650,-(bottom-top)/2+bottom,paint);

6. Paint方法介绍
reset() //重置Paint。

 setFlags(int flags)//设置一些标志,比如抗锯齿,下划线等等。

 setDither(boolean dither)//设置是否抖动,如果不设置感觉就会有一些僵硬的线条,如果设置图像就会看的更柔和一些

setLinearText(boolean linearText) //这个是文本缓存,设置线性文本,如果设置为true就不需要缓存

setSubpixelText(boolean subpixelText)//设置亚像素,是对文本的一种优化设置,可以让文字看起来更加清晰明显

setUnderlineText(boolean underlineText)//设置文本的下划线

setStrikeThruText(boolean strikeThruText)//设置文本的删除线

setFakeBoldText(boolean fakeBoldText)//设置文本粗体

setFilterBitmap(boolean filter)//对位图进行滤波处理,如果该项设置为true,则图像在动画进行中会滤掉对Bitmap图像的优化操作,加快显示 

setStrokeMiter(float miter)//当style为Stroke或StrokeAndFill时设置连接处的倾斜度,这个值必须大于1,锐角越接近0,miter值得上限越大,也就是<=MITERmax时都有倾斜
   paint.setStrokeWidth(30);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeMiter((float)3);
        Path path = new Path();
        path.moveTo(0,30);
        path.lineTo(400,250);
        path.lineTo(300,30);

        canvas.drawPath(path,paint);
        path.reset();
        paint.setStrokeMiter((float)2);
        path.moveTo(300,300);
        path.lineTo(500,300);
        path.lineTo(400,550);
        canvas.drawPath(path,paint);

setShader(Shader shader)//设置着色器,用来给图像着色的,绘制出各种渐变效果,有BitmapShader,ComposeShader,LinearGradient,RadialGradient,SweepGradient几种

BitmapShader
构造方法:BitmapShader (Bitmap bitmap, Shader.TileMode tileX, Shader.TileMode tileY)

第一个参数:要处理的bitmap对象
第二个参数:在X轴处理的效果,Shader.TileMode里有三种模式:CLAMP、MIRROR和REPETA
第三个参数:在Y轴处理的效果,Shader.TileMode里有三种模式:CLAMP、MIRROR和REPETA

Shader.TileMode.CLAMP会将边缘的一个像素进行拉伸、扩展


拉伸后效果
拉伸后效果

Shader.TileMode.MIRROR模式作用是镜像

Shader.TileMode.REPEAT
这个应该是重复模式,和镜像十分类似,但是不是翻转复制,而是平移复制。(x轴方向平移复制,y轴方向镜像复制)

LinearGradient
构造函数:public LinearGradient (float x0, float y0, float x1, float y1, int color0, int color1, Shader.TileMode tile)
(x0,y0)表示渐变的起点坐标而(x1,y1)则表示渐变的终点坐标,这两点都是相对于屏幕坐标系而言的,而color0和color1则表示起点的颜色和终点的颜色,TileMode和上面讲的完全一致。
[(x0,y0,x1,y1)范围为三角形(x0,y0)(2x1-x0,y0)(x0,2y1-y0)自己想的)]

 paint.setShader(new LinearGradient(0,0,100,100,Color.RED,Color.YELLOW, Shader.TileMode.MIRROR));
        canvas.drawRect(new RectF(0,0,400,400),paint);

另一个构造方法:public LinearGradient (float x0, float y0, float x1, float y1, int[] colors, float[] positions, Shader.TileMode tile)
colors和positions都是数组,positions可以为空,为空时系统自动调整,颜色变化是线性的,在pos[i+1]-pos[i]位置线性到达color[i+1]


        paint.setShader(new LinearGradient(0,0,200,200,new int[]{Color.RED,Color.BLUE,Color.YELLOW},
        new float[]{0F,0.4F,1F}, Shader.TileMode.REPEAT));
        canvas.drawRect(new RectF(0,0,400,400),paint);

绘制图片阴影

 canvas.drawColor(Color.GRAY);
        int x = 200, y = 200;
        // 获取源图
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.apic);
        // 实例化一个矩阵对象
        Matrix matrix = new Matrix();
        matrix.setScale(1F,-1F);//第一个参数表示x缩放,第二参数表示y的缩放
        Bitmap refBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        // 绘制好原图
        canvas.drawBitmap(bitmap, x, y, null);
        // 保存图层。ALL_SAVE_FLAG保存所有信息,包括裁剪区域和矩阵变化,restore()返回最上一层
        int sc = canvas.saveLayer(x, y + bitmap.getHeight(), x + bitmap.getWidth(), y + bitmap.getHeight() * 2, null, Canvas.ALL_SAVE_FLAG);
        // 绘制倒影图片,绘制的区域紧贴原图的底部
        canvas.drawBitmap(refBitmap, x, y + bitmap.getHeight(),null);
        // 设置好混合模式
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));//显示src和des重叠的src部分
        paint.setShader(new LinearGradient(x, y + bitmap.getHeight(),x, y + bitmap.getHeight() +
                bitmap.getHeight() / 4,Color.BLACK, Color.TRANSPARENT, Shader.TileMode.CLAMP));
        // 画一个矩形区域,作为目标图片,用来做混合模式
        canvas.drawRect(x, y + bitmap.getHeight(), x + refBitmap.getWidth(), y + bitmap.getHeight() * 2, paint);
        paint.reset();
        canvas.restoreToCount(sc);//restoreToCount()返回到sc层,类似于堆栈一个一个取出来

为了看清效果,我把倒影图和原图大小变得不一样,倒影图比原图小20px;

SweepGradient
它的意思是梯度渐变,也称之为扫描式渐变,因为其效果有点类似雷达的扫描效果
构造方法:SweepGradient(float cx, float cy, int color0, int color1)

  paint.setShader(new SweepGradient(100,100,Color.RED,Color.YELLOW));
      canvas.drawRect(new RectF(0,0,200,200),paint);

效果:

构造方法:
SweepGradient(float cx, float cy, int[] colors, float[] positions)

 paint.setShader(new SweepGradient(100,100,new int[]{Color.RED,Color.BLUE,Color.TRANSPARENT},new float[]{0F,0.4F,1.0F}));//Color.RED->Color.BLUE是从0->0.4,position是相对这个区域的,postion可以为null
      canvas.drawRect(new RectF(0,0,200,200),paint);

效果:

RadialGradient
径向渐变,径向渐变说的简单点就是个圆形中心向四周渐变的效果
构造方法:
RadialGradient (float centerX, float centerY, float radius, int centerColor, int edgeColor, Shader.TileMode tileMode)

RadialGradient (float centerX, float centerY, float radius, int[] colors, float[] stops, Shader.TileMode tileMode)

  paint.setShader(new RadialGradient(100,100,100,Color.RED,Color.BLUE, Shader.TileMode.CLAMP));
      canvas.drawRect(new RectF(0,0,200,200),paint);

效果:

       paint.setShader(new RadialGradient(100,100,100,new int[]{Color.RED,Color.BLUE,Color.YELLOW}, new float[]{0,0.5f,1.0f},Shader.TileMode.CLAMP));
      canvas.drawRect(new RectF(0,0,200,200),paint);

效果:

ComposeShader
构造方法:ComposeShader (Shader shaderA, Shader shaderB, Xfermode mode)
ComposeShader (Shader shaderA, Shader shaderB, PorterDuff.Mode mode)
一般是一个BitmapShader+一个XXGradient;

Shader shader = new BitmapShader(BitmapFactory.decodeResource(getResources(),R.drawable.apic), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        Shader shader01 = new SweepGradient(200,200,new int[]{Color.YELLOW,Color.RED,Color.BLUE},new float[]{0.25f,0.5f,0.75f});
       paint.setShader(new ComposeShader(shader01, shader, PorterDuff.Mode.MULTIPLY));
        canvas.drawRect(0, 0, 400, 400, paint);

效果:

Shader And Matrix

 Shader shader = new BitmapShader(BitmapFactory.decodeResource(getResources(),R.drawable.apic), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        Matrix matrix = new Matrix();
        matrix.setTranslate(100,100);
        shader.setLocalMatrix(matrix);
        paint.setShader(shader);
        canvas.drawRect(0, 0, 400, 400, paint);

效果:
这里写图片描述

 Shader shader = new BitmapShader(BitmapFactory.decodeResource(getResources(),R.drawable.apic), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        Matrix matrix = new Matrix();
        matrix.postTranslate(200,100);
        matrix.preRotate(45);
        shader.setLocalMatrix(matrix);
        paint.setShader(shader);
        canvas.drawRect(0, 0, 400, 400, paint);

效果:

setColorFilter(ColorFilter filter)//设置画笔颜色过滤器,有ColorMatrixColorFilter,LightingColorFilter,PorterDuffColorFilter几种

先介绍ColorMatrix:
颜色矩阵的计算:
这里写图片描述

ColorMatrix函数介绍:
色调调节setRotate(int axis, float degrees)



效果叠加
preConcat(ColorMatrix prematrix)和postConcat(ColorMatrix postmatrix)两个方法分别是将目标效果矩阵放在本矩阵之前和放在本矩阵之后,由于矩阵的乘法一般不满足交换律,因此前后关系会对效果有不同的影响。

ColorMatrixColorFilter

reset();
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.apic);
        canvas.drawBitmap(bitmap,100,0,paint);
        paint.setColorFilter(new ColorMatrixColorFilter(a));
        canvas.drawBitmap(bitmap,100,500,paint);
        ColorMatrix colorMatrix = new ColorMatrix();
        colorMatrix.setSaturation(0);
        paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
        canvas.drawBitmap(bitmap,100,1000,paint);

LightingColorFilter

 Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.apic);
        canvas.drawBitmap(bitmap,100,0,paint);
        paint.setColorFilter(new LightingColorFilter(0x888888,0x000000));
        canvas.drawBitmap(bitmap,100,500,paint);
        paint.setColorFilter(new LightingColorFilter(0x888888,0x555555));
        canvas.drawBitmap(bitmap,100,1000,paint);

PorterDuffColorFilter
构造方法:public PorterDuffColorFilter(int srcColor, PorterDuff.Mode mode)

  Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.apic);
        paint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY));
        canvas.drawBitmap(bitmap,100,0,paint);

PorterDuff.Mode种类

setPathEffect(PathEffect effect)//设置绘制路径的效果,有ComposePathEffect,CornerPathEffect,DashPathEffect,DiscretePathEffect,PathDashPathEffect,SumPathEffect几种

CornerPathEffect:
构造函数:CornerPathEffect(float radius)
参数radius代表了半径,这里的半径就是塞进拐角处圆形的半径,即是用多大半径的圆弧来替换这个拐角。

 Path path = new Path();
        path.moveTo(100,400);
        path.rLineTo(400,400);
        path.rLineTo(100,-400);
        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(Color.BLUE);
        paint.setPathEffect(new CornerPathEffect(100));
        canvas.drawPath(path,paint);

DashPathEffect
构造函数:DashPathEffect(float intervals[], float phase)
其中intervals是间隔,他是一个数组,其中数值必须为偶数,2个为一对,必须成对出现,一对中的第一个代表了线段长度(为0则绘制),第二个代表了空白长度(为0则不留空白)这里可以看出来其实线段2中是由两对数值组成的值如下:

float[] intervals = {100,20,200,50};
参数中phase(假设是80)代表了相位表示从intervals 80开始,也就是先绘制100-80=20的实线,然后绘制20空白,让后绘制200实线,然后绘制50空白,接着绘制100实线,以此类推

float intervals[] = {100,30,200,50};
        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(Color.BLUE);
        paint.setPathEffect(new DashPathEffect(intervals,0));
        Path path = new Path();
        path.moveTo(100,500);
        path.rLineTo(500,500);
        path.rLineTo(100,-500);
        canvas.drawPath(path,paint);
        path.reset();
        path.moveTo(100,900);
        path.rLineTo(500,500);
        path.rLineTo(500,-500);
        canvas.drawPath(path,paint);

DiscretePathEffect

构造函数: DiscretePathEffect(float segmentLength, float deviation)
这里有两个参数,第一个segmentLength字面上看就是段长,deviation代表偏差值。
参数一:指定了原始线段被切分成多长的线段,比如原始线段长度为100.段长设置为20,那么就被切成了5段。
参数二:指定了切割后的小线段于原始位置的偏离距离。

  paint.setStyle(Paint.Style.STROKE);
        paint.setColor(Color.BLUE);
        paint.setPathEffect(new DiscretePathEffect(10,10));
        Path path = new Path();
        path.moveTo(100,500);
        path.rLineTo(500,500);
        path.rLineTo(100,-500);
        canvas.drawPath(path,paint);
        paint.setPathEffect(new DiscretePathEffect(10,20));
        path.reset();
        path.moveTo(100,900);
        path.rLineTo(500,500);
        path.rLineTo(500,-500);
        canvas.drawPath(path,paint);

PathDashPathEffect
PathDashPathEffect(Path shape, float advance, float phase,Style style)
shape:代表了绘制的形状,这里是一个三角形
advace:绘制位移,上一次绘制这个三角形,和下一次绘制三角形起点之间的位移
phase:相位,于之前讲解的相同
style:风格,这里后面三条线就是因为这个参数引起的不同

Style是一个枚举,值如下
TRANSLATE(0), //平移
ROTATE(1), //旋转
MORPH(2); //变形

     Path pathDash = new Path();
        pathDash.rLineTo(10,10);
        pathDash.rLineTo(10,-10);
        pathDash.close();
        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(Color.BLUE);
        paint.setPathEffect(new PathDashPathEffect(pathDash,35,0, PathDashPathEffect.Style.TRANSLATE));
        Path path = new Path();
        path.moveTo(100,500);
        path.rLineTo(500,500);
        path.rLineTo(100,-500);
        canvas.drawPath(path,paint);
        paint.setPathEffect(new PathDashPathEffect(pathDash,35,0, PathDashPathEffect.Style.ROTATE));
        path.reset();
        path.moveTo(100,900);
        path.rLineTo(500,500);
        path.rLineTo(500,-500);
        canvas.drawPath(path,paint);

ComposePathEffect和SumPathEffect

 float intervals[] = {100,30};
        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(Color.BLUE);
        paint.setPathEffect(new ComposePathEffect(new DashPathEffect(intervals,0),new CornerPathEffect(100)));
        Path path = new Path();
        path.moveTo(100,500);
        path.rLineTo(500,500);
        path.rLineTo(100,-500);
        canvas.drawPath(path,paint);
        paint.setPathEffect(new SumPathEffect(new DashPathEffect(intervals,0),new CornerPathEffect(100)));
        path.reset();
        path.moveTo(100,900);
        path.rLineTo(500,500);
        path.rLineTo(500,-500);
        canvas.drawPath(path,paint);

线段1是compose,线段2是sum,看图就已经非常明显,sum只是简单的叠加效果,而compose是组合效果。

setMaskFilter(MaskFilter maskfilter)//对图像进行一定的处理,实现滤镜的效果,如滤化,立体等,有BlurMaskFilter,EmbossMaskFilter几种
BlurMaskFilter:
构造函数:BlurMaskFilter(float radius, BlurMaskFilter.Blur style)

第一个参数:radius很容易理解,值越大我们的阴影越扩散,用过PS的人会很容易理解,其实就是阴影范围。
第二个参数:style表示的是模糊的类型,有SOLID,NORMAL,OUTER和INNER

 setLayerType(LAYER_TYPE_SOFTWARE, null);//关闭硬件加速
  paint.setColor(Color.BLUE);
        paint.setMaskFilter(new BlurMaskFilter(30, BlurMaskFilter.Blur.SOLID));
        canvas.drawRect(new RectF(100,100,500,500),paint);
        paint.setMaskFilter(new BlurMaskFilter(30, BlurMaskFilter.Blur.NORMAL));
        canvas.drawRect(new RectF(100,600,500,1000),paint);
        paint.setMaskFilter(new BlurMaskFilter(30, BlurMaskFilter.Blur.OUTER));
        canvas.drawRect(new RectF(600,100,1000,500),paint);
        paint.setMaskFilter(new BlurMaskFilter(30, BlurMaskFilter.Blur.INNER));
        canvas.drawRect(new RectF(600,600,1000,1000),paint);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值