美文网首页
自定义View(二)- Paint

自定义View(二)- Paint

作者: TianFB | 来源:发表于2019-05-27 14:57 被阅读0次

    自定义View(一)- 流程

    在上一篇文章中我们分析了自定义View的流程,这片文章我们来分析一下绘制过程中的 Paint 类的API

    Paint API

    我们只看一些常用的API

    1. setColor 设置画笔的颜色
      void setColor(@ColorInt int color)
    
    2. setARGB 设置画笔的ARGB值
    /**
    *   a,r,g,b的取值范围都是0~255
    */
      void setARGB(int a, int r, int g, int b)
    
    3. setAlpha 设置画笔的透明度,0为透明
    /**
    *   a的取值范围都是0~255
    */
      void setAlpha(int a)
    
    4. setAntiAlias 设置是否抗锯齿
      void setAntiAlias(boolean aa)
    
    5. setDither 设置是否防抖动,设置true会图像更加平滑饱满,图像更清晰
      void setDither(boolean dither)
    
    6. setStyle 设置画笔的样式
      void setStyle(Style style)
    

    以下为画笔的样式,我们以使用宽为b的画笔绘制一个半径为r的园为例。

    • Paint.Style.FILL 绘制一个半径为r的圆
    • Paint.Style.STROKE 绘制一个内径为(r-b/2)宽为b的圆环
    • Paint.Style.FILL_AND_STROKE 绘制一个半径为(r+b/2)的圆
    7. setStrokeWidth 设置画笔的宽
      void setStrokeWidth(float width)
    
    8. setStrokeJoin 设置折线处的样式
      void setStrokeJoin(Join join)
    
    image.png
    9.setStrokeCap 设置线帽
    void setStrokeCap(Cap cap)
    
    image.png
    10.setFilterBitmap 设置双线性过滤 true时提高图片的过渡效果
    void setFilterBitmap(boolean filter)
    
    image.png
    11. setXfermode 设置图层混合模式
    image.png

    上图是16中混合模式,还有两种不常用的。接下来我们一一介绍。图中的黄色的圆为dst(先绘制的)目标图,蓝色的矩形是src(后绘制的)源图。所有的模式都是作用在src上面的。
    PorterDuff.mode.CLEAR 清除src源图及相交部分
    PorterDuff.mode.SRC 显示src源图
    PorterDuff.mode.DST 显示dst目标图
    PorterDuff.mode.SRC_OVER dst、src都显示src在上层
    PorterDuff.mode.DST_OVER dst、src都显示dst在上层
    PorterDuff.mode.SRC_IN src在上层显示并清除src的非交集部分
    PorterDuff.mode.DST_IN src在下层显示并清除src的非交集部分
    PorterDuff.mode.SRC_OUT 显示src的非交集部分,交集部分透明
    PorterDuff.mode.DST_OUT 清除src的非交集部分,交集部分透明
    PorterDuff.mode.SRC_ATOP 取src的交集部分和dst的非交集部分
    PorterDuff.mode.DST_ATOP 取dst的交集部分和src的非交集部分
    PorterDuff.mode.XOR 交集部分变透明
    PorterDuff.mode.DARKEN 交集部分颜色加深
    PorterDuff.mode.LIGHTEN 交集部分颜色变亮
    PorterDuff.mode.MULTIPLY 取交集部分颜色叠加
    PorterDuff.mode.SCREEN 交集部分滤色
    PorterDuff.mode.ADD 交集部分饱和度相加
    PorterDuff.mode.OVER 交集部分叠加

    12. setShader 设置着色器
      Shader setShader(Shader shader)
    

    我们分析一下系统提供的Shader的子类

    • LinearGradient 线性渐变
    LinearGradient(float x0, float y0, float x1, float y1, @NonNull @ColorInt int colors[],
    @Nullable float positions[], @NonNull TileMode tile)
    

    x0,y0 表示开始点的位置
    x1,y1表示结束点的位置
    colors[] 颜色的数组
    positions[] 指定各开始的颜色的位置取值范围 0~1,为null时颜色均匀分布
    TileMode 表示重复模式 (CLAMP 重复最后一个像素点、REPEAT 整个重复、MIRROR 镜像重复)

     LinearGradient(float x0, float y0, float x1, float y1,@ColorInt int color0,
     @ColorInt int color1,@NonNull TileMode tile)
    

    该构造函数只能指定两个颜色
    构造函数中两个点的连线方向决定了颜色的渐变方向。

     paint.setShader(new LinearGradient(0,0,500,0,new int[]{Color.RED,Color.YELLOW},
              new float[]{0,1}, Shader.TileMode.REPEAT));
     canvas.drawRect(0,0,1000,1000,paint);
    
    image.png
    • SweepGradient 扫描式渐变
    SweepGradient(float cx, float cy,
                @NonNull @ColorInt int colors[], @Nullable float positions[])
    

    cx,cy 表示圆心
    colors 表示渐变颜色的数组
    positions 各颜色开始的位置0~1

    SweepGradient(float cx, float cy, @ColorInt int color0, @ColorInt int color1)
    

    设置两个颜色的构造函数

    paint.setShader(new SweepGradient(500,500,new int[]{Color.RED,Color.YELLOW},new float[]{0,1}));
    canvas.drawRect(0,0,1000,1000,paint);
    
    image.png
    • RadialGradient 径向渐变
    RadialGradient(float centerX, float centerY, float radius,@NonNull @ColorInt int colors[],
     @Nullable float stops[],@NonNull TileMode tileMode)
    

    centerX,centerY 指定一个圆心
    radius 指定半径
    colors 指定颜色的数组
    stops 指定每个颜色的结束位置
    TileMode 重复模式

    RadialGradient(float centerX, float centerY, float radius,
                @ColorInt int centerColor, @ColorInt int edgeColor, @NonNull TileMode tileMode)
    

    指定两个颜色的构造函数

    paint.setShader(new RadialGradient(500, 500, 300, new int[]{Color.RED, Color.YELLOW}, new float[]{0, 1}, Shader.TileMode.REPEAT));
    canvas.drawRect(0, 0, 1000, 1000, paint);
    
    image.png
    • BitmapGradient 位图着色器
    BitmapShader(@NonNull Bitmap bitmap, @NonNull TileMode tileX, @NonNull TileMode tileY)
    

    bitmap 指定一个位图
    tileX X方向的重复模式
    tileY Y方向的重复模式

    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bitmap);
    //X、Y方向都重复
    paint.setShader(new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT));
    canvas.drawRect(0, 0, 1000, 1000, paint);
    
    image.png
    • ComposeShader 混合着色器
    ComposeShader(@NonNull Shader shaderA, @NonNull Shader shaderB, @NonNull Xfermode mode)
    ComposeShader(@NonNull Shader shaderA, @NonNull Shader shaderB, @NonNull PorterDuff.Mode mode)
    

    shaderA 着色器,混合模式中的dst
    shaderB 着色器,混合模式中的src
    Xfermode、PorterDuff.Mode 混合模式。Xfermode是一个基类使用时我们使用其子类PorterDuffXfermode。

    LinearGradient linearGradient = new LinearGradient(0, 0, 500, 0, new int[]{Color.RED, Color.YELLOW}, new float[]{0, 1}, Shader.TileMode.REPEAT);
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bitmap);
    BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
    paint.setShader(new ComposeShader(linearGradient,bitmapShader,new PorterDuffXfermode(PorterDuff.Mode.ADD)));
    canvas.drawRect(0, 0, 1000, 1000, paint);
    
    image.png
    13. setColorFilter()设置滤镜效果
    ColorFilter setColorFilter(ColorFilter filter)
    
    • LightingColorFilter
     //LightingColorFilter 滤镜
     //LightingColorFilter(@ColorInt int mul, @ColorInt int add)
     //mul和add都是和颜色值格式相同的int。mul用来和目标颜色值相乘,add是用来和目标颜色值相加
     //R' = R*mul.R/0xff + add.R
     //G' = G*mul.G/0xff + add.G
     //B' = B*mul.B/0Xff + add.B
     //mull 为0xffffff  add为0x000000  时显示的是原图效果
     //要降低某颜色值的效果时修改mul的值,增加修改add对应的值
      LightingColorFilter lightingColorFilter = new LightingColorFilter(0xffffff, 0x000000);
    
    • PorterDuffColorFilter
     //PorterDuffColorFilter 滤镜
     //PorterDuffColorFilter(@ColorInt int color, @NonNull PorterDuff.Mode mode)
     //相当于先创建一个颜色为color的图层,然后使用mode进行图层混合
     PorterDuffColorFilter duffColorFilter = new PorterDuffColorFilter(0xffff0000, PorterDuff.Mode.DARKEN);
    
    • ColorMatrixColorFilter
            //ColorMatrixColorFilter(@NonNull float[] array)  使用一个矩阵数组的构造函数
            //ColorMatrixColorFilter 颜色矩阵
            //使用一个20位的float数组来表示颜色矩阵
            //[
            //   a,b,c,d,e,
            //   f,g,h,i,j,
            //   k,l,m,n,o,
            //   p,q,r,s,t
            // ]
            //使用颜色矩阵的计算方式为
            // R' = R*a+G*b+B*c+A*d+e;
            // G' = R*f+G*g+B*h+A*i+j;
            // B' = R*k+G*l+B*m+A*n+o;
            // A' = R*p+G*q+B*r+A*s+t;
            //设置下面的颜色矩阵原图不变
            //float[] floats = {
            //       1, 0, 0, 0, 0,
            //       0, 1, 0, 0, 0,
            //       0, 0, 1, 0, 0,
            //       0, 0, 0, 1, 0
            //}
            float[] floats = {
                    1, 0, 0, 0, 0,
                    0, 1, 0, 0, 0,
                    0, 0, 1, 0, 0,
                    0, 0, 0, 1, 0
            };
            ColorMatrixColorFilter colorFilter = new ColorMatrixColorFilter(floats);
    
            //ColorMatrixColorFilter(@NonNull ColorMatrix matrix)  使用ColorMatrix的构造函数
            ColorMatrix cm = new ColorMatrix();
            //修改颜色矩阵,该方法也是操作的颜色矩阵的数组
            //r,g,b,a修改是数组中对应的a[0],g[6],m[12],s[18]
            cm.setScale(1,1,1,1);
            //设置饱和度
            //0 为灰色,1 为原色, >1增加饱和度
            cm.setSaturation(0);
            //通过旋转颜色的坐标系来改变颜色矩阵
            //0 表示旋转red  1 表示旋转green  2表示旋转blue
            cm.setRotate(0,100);
            ColorMatrixColorFilter colorFilter = new ColorMatrixColorFilter(cm);
    

    常见的滤镜效果

     // 黑白
        public static final float colormatrix_heibai[] = {
                0.8f, 1.6f, 0.2f, 0, -163.9f,
                0.8f, 1.6f, 0.2f, 0, -163.9f,
                0.8f, 1.6f, 0.2f, 0, -163.9f,
                0, 0, 0, 1.0f, 0};
        // 复古
        public static final float colormatrix_fugu[] = {
                0.9f, 0.0f, 0.0f, 0.0f, 0.0f,
                0.0f, 0.8f, 0.0f, 0.0f, 0.0f,
                0.0f, 0.0f, 0.5f, 0.0f, 0.0f,
                0, 0, 0, 1.0f, 0};
        // 哥特
        public static final float colormatrix_gete[] = {
                1.9f, -0.3f, -0.2f, 0, -87.0f,
                -0.2f, 1.7f, -0.1f, 0, -87.0f,
                -0.1f, -0.6f, 2.0f, 0, -87.0f,
                0, 0, 0, 1.0f, 0};
        // 传统
        public static final float colormatrix_chuan_tong[] = {
                1.0f, 0.0f, 0.0f, 0, -10f,
                0.0f, 1.0f, 0.0f, 0, -10f,
                0.0f, 0.0f, 1.0f, 0, -10f,
                0, 0, 0, 1, 0};
        // 淡雅
        public static final float colormatrix_danya[] = {
                0.6f, 0.3f, 0.1f, 0, 73.3f,
                0.2f, 0.7f, 0.1f, 0, 73.3f,
                0.2f, 0.3f, 0.4f, 0, 73.3f,
                0, 0, 0, 1.0f, 0};
        // 光晕
        public static final float colormatrix_guangyun[] = {
                0.9f, 0, 0, 0, 64.9f,
                0, 0.9f, 0, 0, 64.9f,
                0, 0, 0.9f, 0, 64.9f,
                0, 0, 0, 1.0f, 0};
        // 胶片
        public static final float colormatrix_fanse[] = {
                -1.0f, 0.0f, 0.0f, 0.0f, 255.0f,
                0.0f, -1.0f, 0.0f, 0.0f, 255.0f,
                0.0f, 0.0f, -1.0f, 0.0f, 255.0f,
                0.0f, 0.0f, 0.0f, 1.0f, 0.0f};
        // 褐片
        public static final float colormatrix_hepian[] = {
                1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
                0.0f, 0.8f, 0.0f, 0.0f, 0.0f,
                0.0f, 0.0f, 0.8f, 0.0f, 0.0f,
                0, 0, 0, 1.0f, 0};
        // 怀旧
        public static final float colormatrix_huajiu[] = {
                0.2f, 0.5f, 0.1f, 0, 40.8f,
                0.2f, 0.5f, 0.1f, 0, 40.8f,
                0.2f, 0.5f, 0.1f, 0, 40.8f,
                0, 0, 0, 1, 0};
        // 胶片2
        public static final float colormatrix_jiao_pian[] = {
                0.71f, 0.2f, 0.0f, 0.0f, 60.0f,
                0.0f, 0.94f, 0.0f, 0.0f, 60.0f,
                0.0f, 0.0f, 0.62f, 0.0f, 60.0f,
                0, 0, 0, 1.0f, 0};
        // 蓝调
        public static final float colormatrix_landiao[] = {
                2.1f, -1.4f, 0.6f, 0.0f, -71.0f,
                -0.3f, 2.0f, -0.3f, 0.0f, -71.0f,
                -1.1f, -0.2f, 2.6f, 0.0f, -71.0f,
                0.0f, 0.0f, 0.0f, 1.0f, 0.0f};
        // 浪漫
        public static final float colormatrix_langman[] = {
                0.9f, 0, 0, 0, 63.0f,
                0, 0.9f, 0, 0, 63.0f,
                0, 0, 0.9f, 0, 63.0f,
                0, 0, 0, 1.0f, 0};
        // 锐色
        public static final float colormatrix_ruise[] = {
                4.8f, -1.0f, -0.1f, 0, -388.4f,
                -0.5f, 4.4f, -0.1f, 0, -388.4f,
                -0.5f, -1.0f, 5.2f, 0, -388.4f,
                0, 0, 0, 1.0f, 0};
        // 梦幻
        public static final float colormatrix_menghuan[] = {
                0.8f, 0.3f, 0.1f, 0.0f, 46.5f,
                0.1f, 0.9f, 0.0f, 0.0f, 46.5f,
                0.1f, 0.3f, 0.7f, 0.0f, 46.5f,
                0.0f, 0.0f, 0.0f, 1.0f, 0.0f};
        // 清宁
        public static final float colormatrix_qingning[] = {
                0.9f, 0, 0, 0, 0,
                0, 1.1f, 0, 0, 0,
                0, 0, 0.9f, 0, 0,
                0, 0, 0, 1.0f, 0};
    
        // 夜色
        public static final float colormatrix_yese[] = {
                1.0f, 0.0f, 0.0f, 0.0f, -66.6f,
                0.0f, 1.1f, 0.0f, 0.0f, -66.6f,
                0.0f, 0.0f, 1.0f, 0.0f, -66.6f,
                0.0f, 0.0f, 0.0f, 1.0f, 0.0f};
        // 酒红
        public static final float colormatrix_jiuhong[] = {
                1.2f, 0.0f, 0.0f, 0.0f, 0.0f,
                0.0f, 0.9f, 0.0f, 0.0f, 0.0f,
                0.0f, 0.0f, 0.8f, 0.0f, 0.0f,
                0, 0, 0, 1.0f, 0};
    
        // 湖光掠影
        public static final float colormatrix_huguang[] = {
                0.8f, 0.0f, 0.0f, 0.0f, 0.0f,
                0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
                0.0f, 0.0f, 0.9f, 0.0f, 0.0f,
                0, 0, 0, 1.0f, 0};
        // 泛黄
        public static final float colormatrix_huan_huang[] = {
                1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
                0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
                0.0f, 0.0f, 0.5f, 0.0f, 0.0f,
                0, 0, 0, 1.0f, 0};
    
    image.png
    image.png
    image.png
    image.png
    14.setMaskFilter 这是边缘效果,是用该方法前要关闭硬件加速setLayerType(LAYER_TYPE_SOFTWARE,null);
    MaskFilter setMaskFilter(MaskFilter maskfilter)
    
    • BlurMaskFilter 对图层的边缘进行模糊处理
    //radius   模糊半径
    //blur       模糊处理的模式
    //NORMAL  向目标内外模糊radius宽的地方,内外延伸的延伸均取自目标的边缘颜色
    //INNER   向目标内部延伸radius宽,取目标边缘外的颜色
    //OUTER  向目标外部延伸radius宽,取目标边缘的颜色,显示目标
    //SOLID  向目标外部延伸radius宽,取目标的颜色,不显示目标
    BlurMaskFilter(float radius, Blur style)
    

    使用上面的模式在黑色的矩形内绘制一个图片


    image.png
    • EmbossMaskFilter 实现浮雕效果
    //direction 表示光源的位置
    //ambient  环境光照强度 0~1
    //specular  反射等级  值越小越亮 
    //blurRadius 照亮前的模糊量,就是光照中亮边的宽度
    EmbossMaskFilter(float[] direction, float ambient, float specular, float blurRadius)
    
    image.png
    15. setTextSize 设置字体的大小
    void setTextSize(float textSize)
    
    16.setTextScaleX 设置字体的缩放比例
    void setTextScaleX(float scaleX) 
    
    17. setTextAlign 设置文本的对齐方式
    void setTextAlign(Align align)
    
    18. setUnderlineText 添加下划线
    void setUnderlineText(boolean underlineText)
    
    19. setStrikeThruText 添加删除线
    void setStrikeThruText(boolean strikeThruText)
    
    20. getTextBounds 获取文本的Rect值,该方法会将测算好的left、top、right、bottom封装到Rect中
    void getTextBounds(String text, int start, int end, Rect bounds)
    getTextBounds(char[] text, int index, int count, Rect bounds)
    
    21. getFontMetrics 获取字体度量的对象
    FontMetrics getFontMetrics()
    public static class FontMetrics {
           /**
            * The maximum distance above the baseline for the tallest glyph in
            * the font at a given text size.
            */
           public float   top;
           /**
            * The recommended distance above the baseline for singled spaced text.
            */
           public float   ascent;
           /**
            * The recommended distance below the baseline for singled spaced text.
            */
           public float   descent;
           /**
            * The maximum distance below the baseline for the lowest glyph in
            * the font at a given text size.
            */
           public float   bottom;
           /**
            * The recommended additional space to add between lines of text.
            */
           public float   leading;
       }
    
    image.png
    22. measureText 获取文本的宽度
    float measureText(char[] text, int index, int count)
    float measureText(String text, int start, int end)
    float measureText(String text)
    float measureText(CharSequence text, int start, int end)
    

    该文并没有将所有的API都罗列出来,剩下的API可查看官方文档Paint_API

    相关文章

      网友评论

          本文标题:自定义View(二)- Paint

          本文链接:https://www.haomeiwen.com/subject/ewdkzqtx.html