自定义控件之绘图篇(四)canvas变换与操作

在Android中,Canvas类是所有图形绘制的核心,它提供了大量的方法用于绘制各种图形元素以及对这些图形进行变换。自定义控件时,熟练掌握Canvas的变换和操作能力是至关重要的。下面,我们将深入探讨Canvas的变换与操作,包括平移、缩放、旋转、剪切以及路径绘制,同时提供一些实用的代码示例。

平移(translate)

平移是Canvas中最基本的变换之一,它通过translate()方法来实现,可以将坐标原点从左上角移动到指定的位置。这在绘制图形时非常有用,可以让我们更灵活地控制图形在屏幕上的位置。

示例代码:

Java

1canvas.translate(100, 100); // 将坐标原点向右下移动100像素
2paint.setColor(Color.BLUE);
3canvas.drawRect(0, 0, 50, 50, paint); // 在新原点处绘制一个蓝色正方形

缩放(scale)

Canvasscale()方法允许你按比例放大或缩小画布上的内容。这对于实现缩放动画或调整复杂图形的大小特别有用。

示例代码:

Java

1canvas.scale(2, 2); // 将画布内容放大两倍
2paint.setColor(Color.GREEN);
3canvas.drawRect(0, 0, 50, 50, paint); // 绘制一个绿色正方形,实际上是100x100

旋转(rotate)

Canvasrotate()方法可以围绕指定的点旋转画布。这对于实现旋转动画或者需要精确角度定位的图形非常有用。

示例代码:

Java

1canvas.rotate(45, 100, 100); // 以(100, 100)为中心点旋转45度
2paint.setColor(Color.YELLOW);
3canvas.drawRect(0, 0, 50, 50, paint); // 绘制一个黄色正方形,但因旋转而变形

剪切(clip)

CanvasclipRect()方法允许你限制绘图的区域,只在指定的矩形区域内绘制图形。这对于实现复杂的遮罩效果或裁剪图形非常有用。

示例代码:

Java

1canvas.clipRect(50, 50, 150, 150); // 只在50x50至150x150的区域内绘制
2paint.setColor(Color.CYAN);
3canvas.drawRect(0, 0, 200, 200, paint); // 实际上只绘制出100x100的正方形

路径绘制(Path)

Path类提供了丰富的功能来创建复杂的图形路径,如直线、曲线、圆弧等。结合Canvas,可以绘制出极其复杂的图形。

示例代码:

Java

1Path path = new Path();
2path.moveTo(50, 50);
3path.lineTo(100, 100);
4path.lineTo(150, 50);
5path.close(); // 形成一个三角形
6paint.setColor(Color.MAGENTA);
7canvas.drawPath(path, paint);

复合变换

在实际应用中,我们经常需要复合使用多种变换。Canvas提供了save()restore()方法来保存和恢复变换状态,这样可以避免变换的累积效应。

示例代码:

Java

1canvas.save(); // 保存当前状态
2canvas.translate(100, 100);
3canvas.rotate(45); // 先平移再旋转
4paint.setColor(Color.RED);
5canvas.drawRect(0, 0, 50, 50, paint);
6canvas.restore(); // 恢复到保存的状态

完整的自定义控件示例

现在,让我们创建一个简单的自定义控件,展示如何在一个View中使用上述的Canvas变换和操作。

Java
1public class TransformView extends View {
2    private Paint mPaint;
3
4    public TransformView(Context context) {
5        super(context);
6        init();
7    }
8
9    public TransformView(Context context, @Nullable AttributeSet attrs) {
10        super(context, attrs);
11        init();
12    }
13
14    private void init() {
15        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
16    }
17
18    @Override
19    protected void onDraw(Canvas canvas) {
20        super.onDraw(canvas);
21        
22        // 平移
23        canvas.save();
24        canvas.translate(100, 100);
25        mPaint.setColor(Color.BLUE);
26        canvas.drawRect(0, 0, 50, 50, mPaint);
27        canvas.restore();
28        
29        // 缩放
30        canvas.save();
31        canvas.translate(200, 100);
32        canvas.scale(2, 2);
33        mPaint.setColor(Color.GREEN);
34        canvas.drawRect(0, 0, 50, 50, mPaint);
35        canvas.restore();
36        
37        // 旋转
38        canvas.save();
39        canvas.translate(300, 100);
40        canvas.rotate(45);
41        mPaint.setColor(Color.YELLOW);
42        canvas.drawRect(0, 0, 50, 50, mPaint);
43        canvas.restore();
44        
45        // 剪切
46        canvas.save();
47        canvas.translate(400, 100);
48        canvas.clipRect(0, 0, 100, 100);
49        mPaint.setColor(Color.CYAN);
50        canvas.drawRect(0, 0, 200, 200, mPaint);
51        canvas.restore();
52        
53        // 路径绘制
54        canvas.save();
55        canvas.translate(50, 200);
56        Path path = new Path();
57        path.moveTo(0, 0);
58        path.lineTo(50, 50);
59        path.lineTo(100, 0);
60        path.close();
61        mPaint.setColor(Color.MAGENTA);
62        canvas.drawPath(path, mPaint);
63        canvas.restore();
64    }
65}

在这个自定义控件中,我们使用了Canvas的各种变换和操作来绘制不同效果的图形,展示了Canvas强大的绘图能力和灵活性。通过这种方式,你可以创建出非常复杂且动态的用户界面组件。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

昇思学习打卡-9-ResNet50图像分类

文章目录 网络介绍数据可视化部分网络实现Building Block结构BottleNet模块 模型训练推理结果可视化学习总结优点不足 网络介绍 在ResNet网络提出之前,传统的卷积神经网络都是将一系列的卷积层和池化层堆叠得到的,但当网络堆叠到一定深度时,…

STM32崩溃问题排查

文章目录 前言1. 问题说明2. STM32(Cortex M4内核)的寄存器3. 崩溃问题分析3.1 崩溃信息的来源是哪里?3.2 崩溃信息中的每个关键字代表的含义3.3 利用崩溃信息去查找造成崩溃的点3.4 keil5中怎么根据地址找到问题点3.5 keil5上编译时怎么输出…

C++模板元编程(二)——完美转发

完美转发指的是函数模板可以将自己的参数“完美”地转发给内部调用的其它函数。所谓完美,即不仅能准确地转发参数的值,还能保证被转发参数的左、右值属性不变。 文章目录 场景旧的方法新的方法内部实现参考文献 场景 思考下面的代码: templ…

深度学习之网络构建

目标 选择合适的神经网络 卷积神经网络(CNN):我们处理图片、视频一般选择CNN 循环神经网络(RNN):我们处理时序数据一般选择RNN 超参数的设置 为什么训练的模型的错误率居高不下 如何调测出最优的超参数 …

【pytorch20】多分类问题

网络结构以及示例 该网络的输出不是一层或两层的,而是一个十层的代表有十分类 新建三个线性层,每个线性层都有w和b的tensor 首先输入维度是784,第一个维度是ch_out,第二个维度才是ch_in(由于后面要转置),没有经过softmax函数和…

C++ 引用——引用的本质

本质:引用的本质在c内部实现是一个指针常量 C推荐用引用技术,因为语法方便,引用本质是指针常量,但是所有的指针操作编译器都帮我们做了 示例: 运行结果:

C++初学者指南-4.诊断---valgrind

C初学者指南-4.诊断—Valgrind Valgrind(内存错误检测工具) 检测常见运行时错误 读/写释放的内存或不正确的堆栈区域使用未初始化的值不正确的内存释放,如双重释放滥用内存分配函数内存泄漏–非故意的内存消耗通常与程序逻辑缺陷有关&#xf…

水箱高低水位浮球液位开关工作原理

工作原理 水箱高低水位浮球液位开关是一种利用浮球随液位升降来实现液位控制的设备。其基本原理是浮球在液体的浮力作用下上下浮动,通过磁性作用驱动与之相连的磁簧开关的开合,从而实现液位的高低控制和报警。当液位升高时,浮球上浮&#xf…

cmake find_package 使用笔记

目录 1 find_package2 config mode2.1 搜索的文件名2.2 搜索路径 3 module mode3.1 搜索的文件名3.2 搜索路径 参考 1 find_package 这是官方文档 下面是学习总结: 首先是find_package的作用是什么?引入预编译的库。 find_package有两种模式&#xff1a…

C语言 指针和数组——指针和二维数组之间的关系

目录 换个角度看二维数组 指向二维数组的行指针 按行指针访问二维数组元素 再换一个角度看二维数组 按列指针访问二维数组元素 二维数组作函数参数 指向二维数组的行指针作函数参数 指向二维数组的列指针作函数参数​编辑 用const保护你传给函数的数据 小结 换个角度看…

使用antd的<Form/>组件获取富文本编辑器输入的数据

前端开发中,嵌入富文本编辑器时,可以通过富文本编辑器自身的事件处理函数将数据传输给后端。有时候,场景稍微复杂点,比如一个输入页面除了要保存富文本编辑器的内容到后端,可能还有一些其他输入组件获取到的数据也一并…

Win10安装MongoDB(详细版)

文章目录 1、安装MongoDB Server1.1. 下载1.2. 安装 2、手动安装MongoDB Compass(GUI可视工具)2.1. 下载2.2.安装 3、测试连接3.1.MongoDB Compass 连接3.2.使用Navicat连接 1、安装MongoDB Server 1.1. 下载 官网下载地址 https://www.mongodb.com/try/download/community …

『大模型笔记』《Pytorch实用教程》(第二版)

『大模型笔记』《Pytorch实用教程》(第二版) 文章目录 一. 《Pytorch实用教程》(第二版)1.1 上篇1.2 中篇1.3 下篇1.4 本书亮点1.5 本书内容及结构二. 参考文献🖥️ 配套代码(开源免费):https://github.com/TingsongYu/PyTorch-Tutorial-2nd📚 在线阅读(开源免费)…

nginx相关概念(反向代理、负载均衡)

1 Nginx 是什么 Nginx是一款轻量级的Web 服务器,其特点是占有内存少,并发能力强 2 Nginx 反向代理 正向代理代替客户端去发送请求反向代理代替服务端接受请求 2.1 正向代理 若客户端无法直接访问到目标服务器 server 则客户端需要配置代理服务器 pr…

正则表达式 先行断言 \S {} 示例

目录 数据准备一. 先行断言1.1 正向先行断言1.2 负向先行断言 二. 配合 {} 和 \S 使用2.1 匹配一个任意非空白字符2.2 匹配任意多个非空白字符2.3 匹配3个非空白字符2.4 匹配至少3个非空白字符2.5 匹配0~3个非空白字符 数据准备 ⏹文件1 0561-10 AAA 123 dfg 345 sss 0561-2…

【电路笔记】-AB类放大器

AB类放大器 文章目录 AB类放大器1、概述2、AB类放大器介绍3、AB类放大器效率4、偏置方法4.1 电压偏置4.2 分压网络4.3 电位器偏置4.4 二极管偏置5、二极管网络和电流源6、AB类放大器的电源分配7、总结1、概述 A类放大器提供非常好的输出线性度,这意味着可以忠实地再现信号,但…

数据结构之“队列”(全方位认识)

🌹个人主页🌹:喜欢草莓熊的bear 🌹专栏🌹:数据结构 前言 上期博客介绍了” 栈 “这个数据结构,他具有先进后出的特点。本期介绍“ 队列 ”这个数据结构,他具有先进先出的特点。 目录…

【无标题】ubuntu的安装和登录

1.安装ubuntu系统并允许root用户登录 一、安装ubuntu分为以下几个步骤: a、在官方网站下载镜像:https://ubuntu.com/ b、选择安装模式为:Try or install Ubuntu (体验或安装) c、选择体验系统或安装系统&#xff1a…

ComfyUI预处理器ControlNet简单介绍与使用(附件工作流)

简介 ControlNet 是一个很强的插件,提供了很多种图片的控制方式,有的可以控制画面的结构,有的可以控制人物的姿势,还有的可以控制图片的画风,这对于提高AI绘画的质量特别有用。接下来就演示几种热门常用的控制方式 1…

RAG理论:ES混合搜索BM25+kNN(cosine)以及归一化

接前一篇:RAG实践:ES混合搜索BM25+kNN(cosine) https://blog.csdn.net/Xin_101/article/details/140230948 本文主要讲解混合搜索相关理论以及计算推导过程, 包括BM25、kNN以及ES中使用混合搜索分数计算过程。 详细讲解: (1)ES中如何通过BM25计算关键词搜索分数; (2)…