记录Paint部分常用的方法

news2024/11/15 20:03:22

Paint部分常用的方法

  • 1、实例化之后Paint的基本配置
  • 2、shader 和 ShadowLayer
  • 3、pathEffect
  • 4、maskFilter
  • 5、colorFilter
  • 6、xfermode

1、实例化之后Paint的基本配置

  • Paint.Align
    Align指定drawText如何将其文本相对于[x,y]坐标进行对齐。默认为LEFT
  • Paint.Cap
    Cap指定了笔画线和路径的开始和结束的处理方法 [BUTT(笔画以路径结束,并且不超出路径),ROUND(笔画凸出成半圆形,圆心在路径的末端),SQUARE(笔画突出为一个正方形,中心位于路径的末端)]
  • Paint.FontMetrics
    类,它描述给定文本大小下字体的各种指标。记住,Y值向下增大,所以这些值是正的,而距离向上的值是负的。这个类由getFontMetrics()返回。
  • Paint.Join
    连接指定了线条和曲线段在描边路径上连接的处理。默认为MITER。
  • Paint.Style
    样式指定所绘制的原语是填充的、描边的,还是两者都有(用相同的颜色)。默认为FILL
  • isAntiAlias抗锯齿
  • isDither防抖动
  • color画笔的颜色
  • strokeWidth画笔的宽
    这里省略其他配置…

2、shader 和 ShadowLayer

简单列子实现效果
在这里插入图片描述

列1


    private fun jcPaint(canvas: Canvas?) {
        Paint().apply {
            setShadowLayer(12f, 5f, 5f, Color.RED)
            isLinearText = true
            val array = IntArray(2)
            array[0] = Color.YELLOW
            array[1] = Color.BLUE




            /*实现线性颜色效果*/
            shader = LinearGradient(
                0f,
                0f,
                100f,
                100f,
                array,
                null,
                Shader.TileMode.MIRROR)


            color = Color.RED
            strokeWidth = 10f
            style = Paint.Style.STROKE
            strokeCap = Paint.Cap.BUTT
            strokeJoin = Paint.Join.ROUND //连接处的处理
            canvas?.drawRect(Rect(10, 10, 400, 400), this)

            val text1 = "style - Paint.Style.STROKE"
            val text2 = "Cap - Paint.Cap.BUTT"
            val text3 = "Join连接处使用圆角 - Paint.Join.ROUNDJoin"
            strokeWidth = 2f
            textSize = 30f
            color = Color.BLUE
            style = Paint.Style.FILL_AND_STROKE
            Paint.ANTI_ALIAS_FLAG


            /**
             * 绘制阴影
             */
            this.setShadowLayer(2f, 0f, 5f, Color.BLUE)
            canvas?.drawText(text1, 20f, 200f, this)

            val tW = this.measureText(text1)
            Log.v("[measureText]", "tw = $tW")


            canvas?.drawText(text2, 20f, 300f, this)
            canvas?.drawText(text3, 20f, 400f, this)
        }
    }

列2

    private fun shader(canvas: Canvas?) {
        /**
         *  围棋子  黑色棋子
         */
        Paint(Paint.ANTI_ALIAS_FLAG)
            .apply {
                color = Color.RED
                strokeWidth = 10f
                style = Paint.Style.FILL
                strokeCap = Paint.Cap.BUTT //结尾处
                strokeJoin = Paint.Join.ROUND //连接处的处理

                val top = 600f
                val left = 30f
                val radius = 100f

                shader = RadialGradient(
                    left + radius, top ,
                    radius+radius*1/4,
                    IntArray(2).apply {
                        this[0] = Color.WHITE
                        this[1] = Color.BLACK
                    },
                    null,
                    Shader.TileMode.CLAMP
                )

                /**
                 * 添加阴影
                 */
                setShadowLayer(6f, 6f, 6f, Color.parseColor("#AACCCCCC"))
                canvas?.drawCircle(left + radius, top, radius, this)


                shader = SweepGradient(0F,0f, listOf<Int>(Color.YELLOW,Color.RED).toIntArray(),
                    null)
                canvas?.drawCircle(left + radius * 3, top, radius, this)
//
//
                /**
                 * 实现线性颜色效果
                 */
                shader = LinearGradient(
                    0f,
                    0f,
                    100f,
                    100f,
                    listOf<Int>(Color.GREEN,Color.BLUE).toIntArray(),
                    null,
                    Shader.TileMode.MIRROR)
                canvas?.drawCircle(left + radius * 5, top, radius, this)



                val b = BitmapFactory.decodeResource(context.resources,R.mipmap.aa)
                shader = BitmapShader(b,Shader.TileMode.MIRROR,Shader.TileMode.MIRROR)
                canvas?.drawCircle(left + radius * 7, top, radius, this)
            }
    }
    

3、pathEffect

1、DiscretePathEffect() 将路径切成segmentLength的行,随机偏离原路径。
2、SumPathEffect() 构造一个PathEffect,其效果是按顺序应用两个效果。(例如,第一个(路径)+第二个(路径))
3、DashPathEffect() interval数组必须包含偶数个条目(>=2),偶数索引指定“开”间隔,奇数索引指定“关”间隔。Phase是interval数组的偏移量(对所有interval的和取mod)。interval数组控制破折号的长度。油漆的strokeWidth控制了破折号的厚度。注意:这个patheeffect只影响画风设置为STROKE或FILL_AND_STROKE的绘图。如果绘图是用style == FILL完成的,它将被忽略。
参数1:间隔-开和关距离的数组
参数2:相位偏移到间隔数组中
4、CornerPathEffect()通过将线段之间的任何锐角替换为指定半径的圆角,转换所绘制的几何图形(STROKE或FILL样式)。
参数:半径-线段之间的圆角。
5、ComposePathEffect() 构造一个PathEffect,其效果是首先应用内部效果和外部PathEffect(例如outer(inner(path)))。
6、PathDashPathEffect()用指定的形状对所绘制的路径进行冲压。这只适用于当油漆样式为STROKE或STROKE_AND_FILL时的绘图。如果油漆的样式是FILL,那么这个效果将被忽略。油漆的描边宽度不会影响结果。

效果:
在这里插入图片描述


    private fun pathEffect(canvas: Canvas?) {
        Paint().apply {

            color = Color.BLUE
            strokeWidth = 5f
            strokeJoin = Paint.Join.ROUND
            style = Paint.Style.STROKE



            pathEffect = DiscretePathEffect(10f,20f)
            canvas?.drawPath(Path().apply {
                moveTo(0f,200f)
                lineTo(300f,100f)
                lineTo(200f,200f)
                lineTo(0f,200f)
            },this)



            pathEffect =  DashPathEffect(FloatArray(2).apply {
                this[0] = 10f
                this[1] = 5f },10f)
            canvas?.drawPath(Path().apply {
                moveTo(250f,200f)
                lineTo(300f,100f)
                lineTo(500f,200f)
                lineTo(250f,200f)
            },this)


            pathEffect = SumPathEffect( DiscretePathEffect(10f,20f),DashPathEffect(FloatArray(2).apply {
                this[0] = 10f
                this[1] = 5f },10f))
            canvas?.drawPath(Path().apply {
                moveTo(0F,400f)
                lineTo(200f,300f)
                lineTo(100f,400f)
                lineTo(0F,400f)
            },this)


            pathEffect = CornerPathEffect(15f)
            canvas?.drawPath(Path().apply {
                moveTo(250f,400f)
                lineTo(300f,300f)
                lineTo(500f,400f)
                lineTo(250f,400f)
            },this)


            pathEffect = ComposePathEffect( DiscretePathEffect(10f,20f),DashPathEffect(FloatArray(2).apply {
                this[0] = 10f
                this[1] = 5f },10f))
            canvas?.drawPath(Path().apply {
                moveTo(550f,400f)
                lineTo(600f,300f)
                lineTo(800f,400f)
                lineTo(550f,400f)
            },this)


            pathEffect = PathDashPathEffect( Path().apply {
                moveTo(0f,8f)
                lineTo(3f,4f)
                lineTo(8f,8f)
                lineTo(0f,8f)
            },5f,10f,PathDashPathEffect.Style.TRANSLATE)

            canvas?.drawPath(Path().apply {
                moveTo(0f,700f)
                lineTo(300f,500f)
                lineTo(700f,700f)
                lineTo(0f,700f)
            },this)
        }
    }

4、maskFilter

1、BlurMaskFilter
这需要一个蒙版,并通过指定的半径模糊其边缘。是否包含原始蒙版,以及模糊是在原始蒙版的边界外、内还是跨界,都由blur enum控制。
2、EmbossMaskFilter
创建一个浮雕蒙版过滤器
已经被弃用 这个子类不受支持,不应该被实例化。

  private fun maskFilter(canvas: Canvas?) {
        Paint().apply {
            color = Color.RED

            maskFilter = BlurMaskFilter(20F,BlurMaskFilter.Blur.SOLID)
            val b0 = BitmapFactory.decodeResource(context.resources, R.mipmap.aa)
            canvas?.drawBitmap(b0,30f,800f,this)


            maskFilter = EmbossMaskFilter(listOf<Float>(30f,30f,30f).toFloatArray(),
                0.2F,
                60F,
                10F)

            val b = BitmapFactory.decodeResource(context.resources, R.mipmap.aa)
            canvas?.drawBitmap(b,30f,800f+b0.height,this)
        }
    }

5、colorFilter

ColorFilter主要用来处理颜色,这里将讲解它的三个子类,ColorMatrixColorFilter,
LightingColorFilter以及PorterDuffColorFilter。
1、ColorMatrixColorFilte 是一种通过4x5颜色矩阵转换颜色的颜色过滤器。这个滤镜可以用来改变像素的饱和度,从YUV转换为RGB等。
参见:ColorMatrix

RGB和Alpha的终值计算方法如下: Red通道终值= a[0] * srcR + a[1] * srcG + a[2] * srcB +
a[3] * srcA + a[4] Green通道终值= a[5] * srcR + a[6] * srcG + a[7] * srcB

  • a[8] * srcA + a[9] Blue通道终值= a[10] * srcR + a[11] * srcG + a[12] * srcB + a[13] * srcA + a[14] Alpha通道终值= a[15]*srcR+a[16]*srcG + a[17] *
    srcB + a[18] * srcA + a[19]

备注: srcR为原图Red通道值,srcG为原图Green通道值,srcB为原图Blue通道值,srcA为原图Alpha通道值。
每个通道的源值和终值都在0到255的范围内。即使计算结果大于255或小于0,值都将被限制在0到255的范围内。

2、LightingColorFilter是一个颜色滤镜,可以用来模拟简单的照明效果。LightingColorFilter由两个参数定义,一个用于将源颜色相乘(称为colorMultiply),另一个用于向源颜色添加(称为colorAdd)。alpha通道不受此颜色滤镜的影响。给定一个源颜色RGB,得到的R’ g ’ b '颜色计算如下:

R’ = R * colorMultiply.R + colorAdd.R
G’ = G * colorMultiply.G + colorAdd.G
B’ = B * colorMultiply.B + colorAdd.B

效果:
在这里插入图片描述
3、PorterDuffColorFilter 是一种颜色滤镜,可用于使用单一颜色和特定波特-达夫复合模式对源像素进行着色。
效果:
在这里插入图片描述

    private fun colorFilter(canvas: Canvas?) {

        //1、ColorMatrixColorFilter
        Paint().apply {
            val MATRIX = floatArrayOf(
                0.3f, 0f, 0f, 0f, 0f,
                0f, 0.5f, 0f, 0f, 0f,
                0f, 0f, 0.5f, 0f, 0f,
                0f, 0f,   0f, 1f, 0f
            )
            val bitmap = BitmapFactory.decodeResource(context.resources, R.mipmap.aa)
            canvas?.drawBitmap(bitmap, 100F, 0F, this);


            val filter = ColorMatrixColorFilter(MATRIX)
            colorFilter = filter
            canvas?.drawBitmap(bitmap, 100F, 500F, this)


            /*方式1*/
            val colorMatrix = ColorMatrix()
            colorMatrix.setSaturation(0f)
            colorFilter = ColorMatrixColorFilter(colorMatrix)
            canvas?.drawBitmap(bitmap, 100F, 1000F, this)
        }

        //2、LightingColorFilter

        Paint().apply {

            val bitmap = BitmapFactory.decodeResource(context.resources, R.mipmap.aa)
            canvas?.drawBitmap(bitmap, 100F, 0F, this);


            val filter = LightingColorFilter(100,0)
            colorFilter = filter
            canvas?.drawBitmap(bitmap, 100F, 500F, this)


            /*方式1*/
            colorFilter = LightingColorFilter(100,100)
            canvas?.drawBitmap(bitmap, 100F, 1000F, this)
        }

        //3、PorterDuffColorFilter 是一种颜色滤镜,可用于使用单一颜色和特定波特-达夫复合模式对源像素进行着色。
        Paint().apply {

            val bitmap = BitmapFactory.decodeResource(context.resources, R.mipmap.aa)
            canvas?.drawBitmap(bitmap, 100F, 0F, this);

            val filter = PorterDuffColorFilter(Color.YELLOW,PorterDuff.Mode.DARKEN)
            colorFilter = filter
            canvas?.drawBitmap(bitmap, 100F, 500F, this)
        }
    }

6、xfermode

在这里插入图片描述
1、PorterDuffXfermode
专门实现Paint的转移模式。参考PorterDuff的文档。关于可用的alpha合成和混合模式的更多信息的模式enum。

效果
在这里插入图片描述

例子

private fun xFerMode(canvas: Canvas) {

        /**
         * 创建一个新的层layer
         */
        canvas.saveLayer(RectF(0f, 0f, canvas.width.toFloat(), canvas.height.toFloat()),Paint())


        Paint().apply {
            strokeWidth=5f
            strokeCap = Paint.Cap.ROUND
            strokeJoin = Paint.Join.ROUND
            style = Paint.Style.FILL_AND_STROKE
            color = Color.GREEN


            /**
             * 步骤1、绘制一个底层圆形图形
             */
            val radius = 100f
            val top = 1200f
            val scr = Bitmap.createBitmap(radius.toInt()*2, radius.toInt()*2,Bitmap.Config.ARGB_8888)
            Canvas(scr).apply {
                drawBitmap(scr,0f,0f,Paint())
                drawCircle(radius,radius,radius,Paint().apply {
                    color = Color.RED
                })
            }
            canvas?.drawBitmap(scr,0f,top,Paint())


            /**
             * 1、PorterDuffXfermode
             */
            xfermode = PorterDuffXfermode(PorterDuff.Mode.MULTIPLY)

            /**
             * 步骤2、绘制上层图片
             */
            val bit = BitmapFactory.decodeResource(context.resources,R.mipmap.aa)
            canvas?.drawBitmap(bit,radius,top+radius,this)
        }
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/391189.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot整合定时任务和邮件发送(邮箱 信息轰炸 整蛊)

SpringBoot整合定时任务和邮件发送&#xff08;邮箱 信息轰炸 整蛊&#xff09; 目录SpringBoot整合定时任务和邮件发送&#xff08;邮箱 信息轰炸 整蛊&#xff09;1.概述2.最佳实践2.1创建项目引入依赖(mail)2.2 修改yml配置文件2.3 启动类添加EnableScheduling注解2.4 执行的…

设计模式(三)--适配器模式(Adapter Pattern)

将一个接口转换成客户希望的另一个接口&#xff0c;适配器模式使接口不兼容的那些类可以一起工作.比如我们日常开发中使用到的slf4j就使用了适配器模式&#xff0c;slf4j提供了一系列打日志的api,底层调用的是log4j或者logback来打日志&#xff0c;而作为调用者&#xff0c;不需…

C++基础(二)—— 类和对象(类的封装)、对象的构造和析构(浅拷贝、深拷贝、explicit、动态分配内存)

【上一篇】C基础&#xff08;一&#xff09;—— C概述、C对C的扩展(作用域、struct类型、引用、内联函数、函数默认参数、函数占位参数、函数重载)1. 类和对象的基本概念1.1 C和C中struct区别c语言struct只有变量c语言struct 既有变量&#xff0c;也有函数1.2 类的封装我们编写…

【建议收藏】超详细的Canal入门,看这篇就够了!!!

概述 canal是阿里巴巴旗下的一款开源项目&#xff0c;纯Java开发。基于数据库增量日志解析&#xff0c;提供增量数据订阅&消费&#xff0c;目前主要支持了MySQL&#xff08;也支持mariaDB&#xff09;。 背景 早期&#xff0c;阿里巴巴B2B公司因为存在杭州和美国双机房部…

Vue3 核心模块源码解析(中)

【Vue3 核心模块源码解析(上)】讲到了 Vue2 与 Vue3的一些区别&#xff0c;Vue3 新特性的使用&#xff0c;以及略微带了一点源码。那么这篇文章就要从Vue3 模块源码解析 与 Vue3 执行逻辑解析这两个方面去给大家剖析 Vue3 的深层次&#xff0c;一起学习起来吧&#xff01; 这里…

6.深入理解SecurityConfigurer

深入理解SecurityConfigurer 一、SecurityConfigurer SecurityConfigurer 在 Spring Security 中是一个非常重要的角色。在前面的内容中曾经多次提到过&#xff0c; Spring Security 过滤器链中的每一个过滤器&#xff0c;都是通过 xxxConfigurer 来进行配置的&#xff0c;而这…

文件跳过回收站删除了常见原因|找回方法

演示机型&#xff1a;技嘉 H310M HD22.0系统版本&#xff1a;Windows 10 专业版软件版本&#xff1a;云骑士数据恢复软件3.21.0.92你有没有遇到文件跳过回收站而直接删除的情况&#xff1f;如果有的话&#xff0c;你是知道是什么原因吗&#xff1f;文件跳过回收站删除了怎么办&…

【JavaScript速成之路】JavaScript数组

&#x1f4c3;个人主页&#xff1a;「小杨」的csdn博客 &#x1f525;系列专栏&#xff1a;【JavaScript速成之路】 &#x1f433;希望大家多多支持&#x1f970;一起进步呀&#xff01; 文章目录前言1&#xff0c;初识数组1.1&#xff0c;数组1.2&#xff0c;创建数组1.3&…

SCI期刊收不收费也有门道,你知道吗?

什么是OA期刊? OA期刊是在互联网上在线出版的学术刊物&#xff0c;英文全称是OpenAccess Journal&#xff0c;中文译为“开放存取期刊”。OA期刊不同于传统的学术期刊如《自然》、《科学》等&#xff0c;采取的是向读者收费的运营模式&#xff0c;读者只有付费订阅&#xff0…

【MySQL】表的数据处理

哈喽&#xff0c;大家好&#xff01;我是保护小周ღ&#xff0c;本期为大家带来的是 MySQL 数据表中数据的基本处理的操作&#xff0c;数据表的增删改查&#xff0c;更多相关知识敬请期待&#xff1a;保护小周ღ *★,*:.☆(&#xffe3;▽&#xffe3;)/$:*.★*一、 添加数据&a…

极简RSS订阅器Miniflux

什么是 Miniflux &#xff1f; Miniflux 是一个极简主义的 RSS 阅读器。它简单、快速、轻便且非常易于使用。Miniflux 是静态编译的单个二进制文件&#xff0c;没有使用任何复杂的框架&#xff0c;也没有外部依赖&#xff0c;简单、快速、轻巧且超级容易安装。支持 Atom、RSS 1…

Docker(五)--Docker网络--源生网络、自定义网络

文章目录一、源生网络1.docker 的网桥---bridge2.host网络模型3.none 网络模型二、自定义网络模型1.bridge驱动2.指定网关和子网3.自定义网络其中内嵌dns解析4.不同网段的容器通信一、源生网络 我们先把server7上的harbor仓库down掉&#xff0c;然后查看网络&#xff0c;可以看…

微服务导学

一、微服务导学1.1 对比单体架构与分布式架构单体架构将业务的所有功能集中再一个项目中开发&#xff0c;打成一个包部署。分布式架构缺点&#xff1a; 模块多导致部署麻烦&#xff1b;架构复杂&#xff0c;难度大1.2 微服务经过良好架构设计的分布式架构方案&#xff0c;微服务…

【Springboot系列】解析Springboot事件机制,从入门到大师

系列文章&#xff1a;Spring Boot学习大纲&#xff0c;可以留言自己想了解的技术点 继续写Springboot系列&#xff0c;争取早点结束。 1、是什么 Spring的事件&#xff08;Application Event&#xff09;为Bean与Bean之间的消息通信提供了支持 事件机制中有三种角色&#x…

RTOS中事件集的实现原理以及实用应用

事件集的原理 RTOS中事件集的实现原理是通过位掩码来实现的。事件集是一种用于在任务之间传递信号的机制。在RTOS中&#xff0c;事件集通常是一个32位的二进制位向量。每个位都代表一个特定的事件&#xff0c;例如信号、标志、定时器等。 当一个任务等待一个或多个事件时&…

Hbase备份与恢复工具Snapshot的基本概念与工作原理

数据库都有相对完善的备份与恢复功能。备份与恢复功能是数据库在数据意外丢失、损坏下的最后一根救命稻草。数据库定期备份、定期演练恢复是当下很多重要业务都在慢慢接受的最佳实践&#xff0c;也是数据库管理者推荐的一种管理规范。HBase数据库最核心的备份与恢复工具——Sna…

Spark+Vue+Springboot 协同过滤额音乐推荐大数据深度学习项目

一、项目背景 随着互联网的发展,大数据的到来,传统的音乐行业受到了很大的冲击,原有的音乐数字化给人们生活带来了极大的便利。随着数字音乐的兴起,各大音乐平台层出不穷,人们在音乐平台上收听音乐的时,常常因为歌曲信息繁杂,而不能找到自己想听的音乐。为了解决这个问题,音乐…

Elasticsearch:使用 Logstash 构建从 Kafka 到 Elasticsearch 的管道 - Nodejs

在我之前的文章 “Elastic&#xff1a;使用 Kafka 部署 Elastic Stack”&#xff0c;我构建了从 Beats > Kafka > Logstash > Elasticsearch 的管道。在今天的文章中&#xff0c;我将描述从 Nodejs > Kafka > Logstash > Elasticsearch 这样的一个数据流。在…

modbus转profinet网关连接ABB变频器在博图程序案例

在博图里PLC无需编程利用兴达易控modbus转Profinet网关,将ABB变频器接入到西门子网络中.用到设备为西门子1200PLC&#xff0c;ABB变频器及兴达易控Modbus转profinet网关一个;兴达易控Modbus转profinet协议转换器&#xff08;XD-MDPN100&#xff09;一台 打开博图添加1200PLC&am…

121.(leaflet篇)leaflet结合echarts4迁徙图

听老人家说:多看美女会长寿 地图之家总目录(订阅之前建议先查看该博客) 文章末尾处提供保证可运行完整代码包,运行如有问题,可“私信”博主。 效果如下所示: 下面献上完整代码,代码重要位置会做相应解释 <!DOCTYPE html> <html>