Android Canvas的使用
android.graphics.Canvas
一般在自定义View中,重写 onDraw(Canvas canvas) 方法时用到。
/*** Implement this to do your drawing.** @param canvas the canvas on which the background will be drawn*/@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.xxx // 自己的逻辑}
Paint 的使用
Paint 叫画笔,它决定了颜色、画笔宽度、填充效果等。
Canvas 是搭配 Paint 使用的,使用 Canvas 要先初始化 Paint 。如,
Paint paintPointRed = new Paint();paintPointRed.setColor(Color.RED); // 设置画笔颜色
paintPointRed.setFlags(Paint.ANTI_ALIAS_FLAG); // 设置抗锯齿
paintPointRed.setStrokeWidth(5f); //设置画笔宽度
paintPointRed.setStyle(Paint.Style.STROKE);// 设置只描边,还有填充、填充且描边可选,默认填充
绘制颜色
Canvas.drawColor(int color)
:绘制颜色,参数传具体的颜色值就行。
canvas.drawColor(Color.LTGRAY); 效果就是 View 显示灰色,
绘制点
Canvas.drawPoint(float x, float y, Paint paint)
:在左边(x,y) 处绘制一个点。
Canvas.drawPoints(@Size(multiple = 2) @NonNull float[] pts, @NonNull Paint paint)
:根据数组 pts 绘制多个点。
根据传入的单个坐标或者坐标数组画点,
private Paint paintPointRed = new Paint();
private Paint paintPointGreen = new Paint();paintPointRed.setColor(Color.RED);
paintPointRed.setFlags(Paint.ANTI_ALIAS_FLAG);
paintPointRed.setStrokeWidth(5f);paintPointGreen.setColor(Color.GREEN);
paintPointGreen.setFlags(Paint.ANTI_ALIAS_FLAG);
paintPointGreen.setStrokeWidth(20f);canvas.drawPoint(100,50, paintPointRed);canvas.drawPoints(new float[]{200,80,220,60,240,40,},paintPointRed);canvas.drawPoints(new float[]{200,200,300,300,400,400,500,500,600,600,},paintPointGreen);
我用的两种画笔,画笔颜色不同、宽度不同,效果对比,
从例子中可以看出,画布坐标原点(0,0) 是显示区域左上角 。
画布坐标
默认情况下,坐标原点(0,0) 是显示区域左上角。
使用 Canvas.translate(float dx, float dy)
可以修改画布的坐标原点,
例,先画了点,修改画布坐标原点后,再画同样的点,
canvas.drawPoint(100,50, paintPointRed);canvas.drawPoints(new float[]{200,80,220,60,240,40,},paintPointRed);canvas.drawPoints(new float[]{200,200,300,300,400,400,500,500,600,600,},paintPointGreen);canvas.translate(800,0); //修改画布坐标原点canvas.drawPoint(100,50, paintPointRed);canvas.drawPoints(new float[]{200,80,220,60,240,40,},paintPointRed);canvas.drawPoints(new float[]{200,200,300,300,400,400,500,500,600,600,},paintPointGreen);
效果如图,说明画布坐标原点已经变更了。画布坐标原点不同,显示效果不同,so ,变更画布坐标原点有风险,修改需谨慎。
绘制直线
Canvas.drawLine(float startX, float startY, float stopX, float stopY,NonNull Paint paint)
:通过两个点 (startX, startY) 、(stopX, stopY) 确定一条直线。
画笔决定线条的颜色、宽度等。
private Paint paintLine1 = new Paint();
private Paint paintLine2 = new Paint();paintLine1.setColor(Color.RED);
paintLine1.setFlags(Paint.ANTI_ALIAS_FLAG);
paintLine2.setColor(Color.YELLOW);
paintLine2.setFlags(Paint.ANTI_ALIAS_FLAG);
paintLine2.setStrokeWidth(20f);canvas.drawLine(100,100, 500,100, paintLine1);
canvas.drawLine(100,200, 500,400, paintLine1);
canvas.drawLine(100,500, 200,600, paintLine2);
效果,
绘制曲线
Canvas.drawPath(@NonNull Path path, @NonNull Paint paint)
:通过 Path 构建贝塞尔曲线,依据 path 画出曲线。
private Paint paintLinePath = new Paint();
paintLinePath.setColor(Color.MAGENTA);
paintLinePath.setFlags(Paint.ANTI_ALIAS_FLAG);
paintLinePath.setStrokeWidth(5f);Path path = new Path();
path.moveTo(200,200);
path.cubicTo(200,700,800,700, 1000,300);
canvas.drawPath(path, paintLinePath);
效果,
不对啊,说是画线,怎么出来个图像,按理应该只有下面弧形才对。
不着急,这和画笔的 Style 有关,默认是填充效果 Paint.Style.FILL
,修改为描边效果 Paint.Style.STROKE
,
paintLinePath.setStyle(Paint.Style.FILL);
效果如图,nice
绘制文字
drawText(String text, float x, float y, Paint paint)
:在坐标 (x,y) 处绘制文本。
drawText(String text, int start, int end, float x, float y,Paint paint)
:在坐标 (x,y) 处绘制文本,文本只显示第 start 到第 end-1 位 。
canvas.drawText("CanvasActivity", 100 , 300, paintText);
canvas.drawText("CanvasActivity", 2,9,100 , 350, paintText);
效果,
绘制圆形
Canvas.drawCircle(float cx, float cy, float radius, Paint paint)
:以坐标 (cx,cy) 为圆心绘制半径为 radius 的圆形。
private Paint paintCircleMagenta = new Paint();
private Paint paintCircleGreen = new Paint();paintCircleMagenta.setColor(Color.MAGENTA);
paintCircleMagenta.setFlags(Paint.ANTI_ALIAS_FLAG);
paintCircleGreen.setColor(Color.GREEN);
paintCircleGreen.setFlags(Paint.ANTI_ALIAS_FLAG);canvas.drawCircle(100,100,50, paintCircleMagenta);canvas.drawCircle(400,300,100, paintCircleGreen);canvas.drawCircle(700,300,100, paintCircleGreen);
canvas.drawCircle(700,300,50, paintCircleMagenta);canvas.drawCircle(1000,300,50, paintCircleMagenta);
canvas.drawCircle(1000,300,100, paintCircleGreen);
效果,
说明后面绘制的图像会覆盖前面绘制的。
绘制椭圆
Canvas.drawOval(RectF oval, Paint paint)
:通过 RectF 确定椭圆位置并绘制。
RectF(float left, float top, float right, float bottom)
: 初始化 RectF 时根据坐标 (left,top)、(right,bottom) 确定矩形的左上角、右下角,得到最大内切椭圆。
Canvas.drawOval(float left, float top, float right, float bottom, Paint paint)
:通过坐标确定椭圆位置并绘制。
个人理解,根据坐标得到矩形,矩形确定最大内切椭圆。
private Paint paintOval1 = new Paint();
paintOval1.setColor(Color.BLUE);
paintOval1.setFlags(Paint.ANTI_ALIAS_FLAG);canvas.drawOval(new RectF(100,100,300,300), paintOval1);
canvas.drawOval(new RectF(400,100,800,300), paintOval1);paintOval1.setStyle(Paint.Style.STROKE);//只描边
paintOval1.setStrokeWidth(5f);
canvas.drawOval(900,100,1100,600, paintOval1);
效果,
绘制弧形
Canvas.drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
:通过 RectF 确定弧形位置并绘制。
Canvas.drawArc(float left, float top, float right, float bottom, float startAngle,float sweepAngle, boolean useCenter, Paint paint)
:通过坐标确定弧形位置并绘制 。
个人理解,根据坐标得到矩形,矩形确定最大内切椭圆,根据参数来截取椭圆区域得到弧形。
private Paint paintArc1 = new Paint();
paintArc1.setColor(Color.CYAN);
paintArc1.setFlags(Paint.ANTI_ALIAS_FLAG);canvas.drawRect(100,100 ,400,300,paintRect3); // 同位置绘制矩形
canvas.drawArc(100,100,400,300,0,90,false,paintArc1);canvas.drawRect(100,500 ,400,700,paintRect3);// 同位置绘制矩形
canvas.drawArc(new RectF(100,500,400,700),270,-90,true,paintArc1);
在同位置先绘制了矩形,方便对比,
效果
以 canvas.drawArc(new RectF(100,500,400,700),270,-90,true,paintArc1); 为例说明参数
- 矩形左上角坐标是(100,500) ,右下角坐标是 (400,700) ,从而得到了最大内切椭圆。
- startAngle :开始点相对比 0° 的角度,顺时针方向(绿色箭头方向)为正方向,所以是 270°。
- sweepAngle :开始点旋转的角度,逆时针方向(蓝色箭头方向)为负方向,所以是 -90° 。
- useCenter :如果设为 true ,则包含椭圆中心,即弧形区域是 起点终点间的弧线 + 起点和椭圆中心的直线 + 终点和椭圆中心的直线 围起来的区域。为 false ,弧形区域是 起点终点间的弧线 + 起点到终点的直线 围起来的区域。
绘制矩形
Canvas.drawRect(@NonNull RectF rect, @NonNull Paint paint)
:通过 RectF 确定矩形位置并绘制。
RectF(float left, float top, float right, float bottom)
: 初始化 RectF 时根据坐标 (left,top)、(right,bottom) 确定矩形的左上角、右下角。
private Paint paintCircleGreen = new Paint();
private Paint paintRectMagenta = new Paint();
paintRectMagenta.setColor(Color.MAGENTA);
paintRectMagenta.setFlags(Paint.ANTI_ALIAS_FLAG);
paintRectGreen.setColor(Color.GREEN);
paintRectGreen.setFlags(Paint.ANTI_ALIAS_FLAG);canvas.drawRect(new RectF(100,100,500,300), paintRectMagenta);
canvas.drawRect(new RectF(500,300,700,500), paintRectGreen);paintRectGreen.setStyle(Paint.Style.STROKE);// 只描边
paintRectGreen.setStrokeWidth(5f);
canvas.drawRect(new RectF(800,300,1000,500), paintRectGreen);
效果,
绘制圆角矩形
Canvas.drawRoundRect(RectF rect, float rx, float ry, @NonNull Paint paint)
:通过 RectF 确定圆角矩形位置并绘制。
Canvas.drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, Paint paint)
: 通过坐标确定圆角矩形位置并绘制,rx 、ry 决定圆角的弧度。
private Paint paintRoundRect = new Paint();
paintRoundRect.setColor(Color.MAGENTA);
paintRoundRect.setFlags(Paint.ANTI_ALIAS_FLAG);canvas.drawRoundRect(new RectF(100,100,300,300), 10,10,paintRoundRect);
canvas.drawRoundRect(new RectF(500,100,700,300), 50,50,paintRoundRect);canvas.drawRoundRect(new RectF(100,400,400,600), 10,10,paintRoundRect);
canvas.drawRoundRect(new RectF(500,400,800,600), 100,100,paintRoundRect);paintRoundRect.setStyle(Paint.Style.STROKE);// 只描边
paintRoundRect.setStrokeWidth(5f);
canvas.drawRoundRect(new RectF(900,100,1100,300), 10 ,10, paintRoundRect);
canvas.drawRoundRect(new RectF(900,400,1200,600), 100 ,100, paintRoundRect);
效果,
相关文章:
Android Canvas的使用
android.graphics.Canvas 一般在自定义View中,重写 onDraw(Canvas canvas) 方法时用到。 /*** Implement this to do your drawing.** param canvas the canvas on which the background will be drawn*/Overrideprotected void onDraw(Canvas canvas) {super.onDra…...
AI批量写文章伪原创:基于ChatGPT长文本模型,实现批量改写文章、批量回答问题(长期更新)
import traceback import openai import osopenai.api_key = ""conversation=[{"role": "system", "content": "You are a helpful assistant."}] max_history_len = 20 first_message = Nonedir = rJ:\ai\input #要改写的文…...
git常用场景记录 | 拉取远程分支A合并到本地分支B - 删除上一次的commit
文章目录 git常用场景记录拉取远程分支A合并到本地分支B本地分支B存在未add与commit的代码 删除上一次的commit已经push到远程库 git常用场景记录 doing,最后更新9.5 拉取远程分支A合并到本地分支B 需求描述 在团队合作时,我自己的本地分支B功能已经实现…...
源码角度解析SpringBoot 自动配置
文章目录 前言一、了解相关注解1.Condition注解2.Enable注解 二、SpringBoot自动配置1.SpringBootApplication注解2.SpringBootConfiguration注解3.EnableAutoConfiguration注解4.Conditional注解 总结 前言 Spring Boot 自动配置是 Spring Boot 的核心特性之一,它…...
【原创】H3C路由器OSPF测试
网络拓扑图 路由器配置: 路由器1上接了4跟线,分别为这四个接口配置IP地址。 # interface GigabitEthernet0/0/0port link-mode routecombo enable copperip address 2.1.1.2 255.255.255.0 # interface GigabitEthernet0/0/1port link-mode routecombo…...
计算机视觉:轨迹预测综述
计算机视觉:轨迹预测综述 轨迹预测的定义轨迹预测的分类基于物理的方法(Physics-based)基于机器学习的方法(Classic Machine Learning-based)基于深度学习的方法(Deep Learning-based)基于强化学…...
三维跨孔电磁波CT数据可视化框架搭建
三维跨孔电磁波CT数据可视化框架搭建 文章目录 三维跨孔电磁波CT数据可视化框架搭建1、三维CT可视化结果2、matlab代码2.1、CT数据格式整理并保存2.2、三维可视化 利用matlab实现对跨孔电磁波CT实测数据反演,并搭建了三维CT数据可视化框架,可装填实测CT反…...
OC和Swift混编,导入头文件‘xxx-Swift.h‘ file not found
在OC的项目里加入Swift代码,创建完桥接文件后,需要倒入Swift头文件,头文件的格式为“项目名-Swift.h”。 如下图,我在Xcode上看到我的项目名为YichangPark,导入 #import "YiChangPark-Swift.h" 之后提示 “Y…...
一文读懂HOOPS Native平台:快速开发桌面端、移动端3D应用程序!
HOOPS Native Platform是用于在桌面和移动平台以及混合现实应用程序上构建3D工程应用程序的首要工具包。它由三个集成良好的软件开发工具包(SDK)组成:HOOPS Visualize、HOOPS Exchange、HOOPS Publish。HOOPS Visualize 是一个强大的图形引擎,适用于本机…...
Scrum工作模式及Scrum工具
Scrum工作模式是一种敏捷软件开发方法,其核心是团队合作和自我组织,旨在通过短周期的迭代开发,实现快速反馈和持续改进。 Scrum工作模式包括以下角色和活动: 1、产品负责人(Product Owner):负…...
[ros][ubuntu]ros在ubuntu18.04上工作空间创建和发布一个话题
构建catkin工作空间 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src catkin_init_workspace cd ~/catkin_ws/ catkin_make 配置环境变量 echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc source ~/.bashrc 检查环境变量 echo $ROS_PACKAGE_PATH…...
我的区块链笔记
区块链 中心化的账本,个人节点和中心节点的地位不对等,中心节点说了算。去中心化,个人节点就是公平的,根据一套规则,叫做公比机制。 区块链的本质,就是数据存储方式 区块链使用密码学算法产生的区块&…...
Spring事务(ACID特性、隔离级别、传播机制、失效场景)
一、事务的ACID特性 原子性(Atomicity) 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。一致性(Consistency) 事务前后数据的完整性必须保持一致。隔离性(Isola…...
机器学习笔记之最优化理论与方法(六)无约束优化问题——最优性条件
机器学习笔记之最优化理论与方法——无约束优化问题[最优性条件] 引言无约束优化问题无约束优化问题最优解的定义 无约束优化问题的最优性条件无约束优化问题的充要条件无约束优化问题的必要条件无约束优化问题的充分条件 引言 本节将介绍无约束优化问题,主要介绍无…...
E5061B/是德科技keysight E5061B网络分析仪
181/2461/8938产品概述 是德科技E5061B(安捷伦)网络分析仪在从5 Hz到3 GHz的宽频率范围内提供通用的高性能网络分析。E5061B提供ENA系列常见的出色RF性能,还提供全面的LF(低频)网络测量能力;包括内置1 Mohm输入的增益相位测试端口。E5061B从低频到高频的…...
2.4 PE结构:节表详细解析
节表(Section Table)是Windows PE/COFF格式的可执行文件中一个非常重要的数据结构,它记录了各个代码段、数据段、资源段、重定向表等在文件中的位置和大小信息,是操作系统加载文件时根据节表来进行各个段的映射和初始化的重要依据…...
Vue2项目练手——通用后台管理项目第五节
Vue2项目练手——通用后台管理项目 首页组件布局面包屑&tag面包屑使用组件使用vuex存储面包屑数据src/store/tab.jssrc/components/CommonAside.vuesrc/components/CommonHeader.vue tag使用组件文件目录CommonTag.vueMain.vuetabs.js 用户管理页新增功能使用的组件页面布局…...
软件工程学术顶会——ESEC/FSE 2022 议题(网络安全方向)清单、摘要与总结
总结 本次会议中网络安全相关议题涵盖区块链、智能合约、符号执行、浏览器API模糊测试等不同研究领域。 热门研究方向: 1. 基于深度学习的漏洞检测与修复 2. 基于AI的自动漏洞修复 3. 模糊测试与漏洞发现 冷门研究方向: 1. 多语言代码的漏洞分析 2. 代码审查中的软件安全 3. 浏…...
从C语言到C++_36(智能指针RAII)auto_ptr+unique_ptr+shared_ptr+weak_ptr
目录 1. 智能指针的引入_内存泄漏 1.1 内存泄漏 1.2 如何避免内存泄漏 2. RAII思想 2.1 RAII解决异常安全问题 2.2 智能指针原理 3. auto_ptr 3.1 auto_ptr模拟代码 4. unique_ptr 4.1 unique_ptr模拟代码 5. shared_ptr 5.1 shared_ptr模拟代码 5.2 循环引用 6.…...
C++信息学奥赛1187:统计字符数
#include <bits/stdc.h> using namespace std; int main() {string arr;cin >> arr; // 输入一个字符串int n, a, max; // 定义变量n, a, maxchar ArrMax; // 定义字符变量ArrMaxn arr.length(); // 获取字符串长度max a 0; // 初始化max和a为0// 外层循环&…...
计算机毕设 大数据商城人流数据分析与可视化 - python 大数据分析
文章目录 0 前言课题背景分析方法与过程初步分析:总体流程:1.数据探索分析2.数据预处理3.构建模型 总结 最后 0 前言 🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到…...
vscode上搭建go开发环境
前言 Go语言介绍: Go语言适合用于开发各种类型的应用程序,包括网络应用、分布式系统、云计算、大数据处理等。由于Go语言具有高效的并发处理能力和内置的网络库,它特别适合构建高并发、高性能的服务器端应用。以下是一些常见的Go语言应用开发…...
10.(Python数模)(预测模型二)LSTM回归网络(1→1)
LSTM回归网络(1→1) 长短期记忆网络 - 通常只称为“LSTM” - 是一种特殊的RNN,能够学习长期的规律。 它们是由Hochreiter&Schmidhuber(1997)首先提出的,并且在后来的工作中被许多人精炼和推广。…...
mac常见问题(五) Mac 无法开机
在mac的使用过程中难免会碰到这样或者那样的问题,本期为您带来Mac 无法开机怎么进行操作。 1、按下 Mac 上的电源按钮。每台 Mac 电脑都有一个电源按钮,通常标有电源符号 。然后检查有没有通电迹象,例如: 发声,例如由风…...
WebSocket与SSE区别
一,websocket WebSocket是HTML5下一种新的协议(websocket协议本质上是一个基于tcp的协议) 它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯的目的 Websocket是一个持久化的协议 websocket的原理 …...
Qt鼠标点击事件处理:显示鼠标点击位置(完整示例)
Qt 入门实战教程(目录) 前驱文章: Qt Creator 创建 Qt 默认窗口程序(推荐) 什么是事件 事件是对各种应用程序需要知道的由应用程序内部或者外部产生的事情或者动作的通称。 事件(event)驱动…...
OpenCV:实现图像的负片
负片 负片是摄影中会经常接触到的一个词语,在最早的胶卷照片冲印中是指经曝光和显影加工后得到的影像。负片操作在很多图像处理软件中也叫反色,其明暗与原图像相反,其色彩则为原图像的补色。例如,颜色值A与颜色值B互为补色&#…...
HZOJ#237. 递归实现排列型枚举
题目描述 从 1−n这 n个整数排成一排并打乱次序,按字典序输出所有可能的选择方案。 输入 输入一个整数 n。(1≤n≤8) 输出 每行一组方案,每组方案中两个数之间用空格分隔。 注意每行最后一个数后没有空格。 样例…...
C++ PIMPL 编程技巧
C PIMPL 编程技巧 文章目录 C PIMPL 编程技巧什么是pimpl?pimpl优点举例实现 什么是pimpl? Pimpl (Pointer to Implementation) 是一种常见的 C 设计模式,用于隐藏类的实现细节,从而减少编译依赖和提高编译速度。它的基本思想是将…...
一个通用的EXCEL生成下载方法
Excel是一个Java开发中必须会用到的东西,之前博主也发过一篇关于使用Excel的文章,但是最近工作中,发现了一个更好的使用方法,所以,就对之前的博客进行总结,然后就有了这篇新的,万能通用的方法说…...
app怎么开发制作/重庆seo网络推广关键词
问题描述 ACM 小组接受了计算机组成原理教研室的一项开发任务,要为计算机组成原理课程开发一款实验面板仿真系统,其中有一项数字显示屏的任务分配给了你。数字显示屏是由一组数字显示单元组成的,每个数字显示单元由七个液晶显示管组成&#…...
珠海网站建设哪家好/海南百度推广seo
利用栈实现表达式的计算。括号匹配。 中缀表达式转换为后缀表达式。 逆波兰表达式的计算 package com.yc.algorithm.stack;import java.util.Scanner; import java.util.Stack;/*** 逆波兰表达式计算* ( 1 - 2 ) * ( 4 5 ) --> -9*/ public class RPN {public static vo…...
wordpress建站教程百科/seo优化网站优化排名
web页面前台的js,就像是一个viewmodel,我们可以把整个页面抽象成一个class viewmodel,然后对这个viewmodel进行操作就可以了。将页面的整个操作封装在一个对象中,思路清晰,有条理,不会觉得很乱。至于这种…...
百度链接收录/seo的基本工作内容
在移动互联网时代,每个人对自己的隐私都是非常的看重的,而每天都在使用的手机储存着大量的数据,如果被轻易破解,那么个人隐私或财产安全就会受到威胁。为了保护用户隐私,如今的手机厂商都费尽心思,不断升级…...
asp net做网站视频/网站开发流程是什么
Zookeeper 集群安装与常用命令使用 JDK下载点击打开链接 Zookeeper 下载 点击打开链接 在三台机器上安装JDK 1. 在linux 上新建一个目录存放 JDK和zookeeper mkdir /usr/local/software 上传JDK和zookeeper 2. 新建一个java 目录 mkdir /usr/local/java cd /usr/local/s…...
成都用设计公司网站/搜索引擎营销的基本方法
一直想学习下设计模式,不过总是被耽搁,今天就从最简单的工厂模式开始吧.记录下来.买了个GOF的设计模式的书,不过自己水平有限,上面的例子又都不是java的,举的例子又不像国内的那种简单, 所以看起来有点吃力,就去网上搜了下看看别人的新的,结果发现大部分内容都一样, 而且大部分…...