操作

API

备注

移动画布

translate(float dx, float dy)

--

画布旋转

rotate(float degrees)

--

画布旋转

rotate(float degrees, float px, float py)

--

画布缩放

scale(float sx, float sy)

--

画布缩放

scale(float sx, float sy, float px, float py)

--

画布错切

skew(float sx, float sy)

--

画布状态保存

save()

--

画布状态保存

save(int saveFlags)

API26弃用

画布状态还原

restore()

--

画布状态还原

restore(int saveCount)

--

一、画布移动

操作

API

备注

移动画布

translate(float dx, float dy)

--

画布移动操作在绘制自定义 View 中非常常用,它能减少不必要的计算,同时让我们在绘制的时候,只需要关注某个小模块的内部位置关系。思路清晰了,做自定义自然也会得心应手一些。

上面方法意为把画布中心移动到某个位置 (dx, dy),在移动的时候,画布上已经绘制的视图并不会移动。下面是我移动了两次的例子:

canvas.translate(50,50);

drawXY(canvas);//绘制坐标系

canvas.translate(350,250)

drawXY(canvas);//绘制坐标系

效果图-g.png

二、旋转

操作

API

备注

画布旋转

rotate(float degrees)

--

画布旋转

rotate(float degrees, float px, float py)

--

参数是旋转角度和旋转中心,在没有旋转中心参数传入的时候,默认旋转中心为 (0 , 0) 。需要注意的是,由于屏幕的坐标系 y 轴向下,所以转动的正方向和习惯的有些不同。

三、缩放

操作

API

备注

画布缩放

scale(float sx, float sy)

--

画布缩放

scale(float sx, float sy, float px, float py)

--

scale 方法中主要看前面两个参数,后面两个参数为旋转中心,在不输入值的时候,默认为(0 , 0)。

degree 取值

备注

(1, +∞)

放大

1

不变

(0, 1)

缩小

(-1, 0)

缩小并翻转 180

-1

翻转 180

(-∞, -1)

放大并翻转 180

这个东西让我想到了高中时候做的小孔成像实验。。。

言归正传,写点代码更容易理解,先是正值 0.5、1.0、1.5、2.0 的效果图:

效果图-g.png

再来是负值 -0.5、-1.0、-1.5、-2.0 的效果图:

效果图-g.png

defree 绝对值取值

备注

(1, +∞)

放大

1

不变

(0, 1)

缩小

然后我发现,对于 scale 来说,我们需要记住下面的表格

defree 绝对值取值

备注

(1, +∞)

放大

1

不变

(0, 1)

缩小

关于正负翻转多少,其实可以参考坐标系里象限的相关知识,大概是这样:

效果图-g.png

隐约记起了自己背 “奇变偶不变,符号看象限” 的日子。

四、错切

操作

API

备注

画布错切

skew(float sx, float sy)

--

错切只提供了一种方法,两个参数为:

sx 画布在 x 轴上的倾斜角度的 tan 值

sy 画布在 y 轴上的倾斜角度的 tan 值

在转换后,会给每个点计算出新的位置,具体计算方法为:

xResult = x + sy * x

yResult = y + sx * y

试了一下 x 轴上 45 度的错切:

效果图-g.png

五、画布快照

操作

API

备注

画布状态保存

save()

--

画布状态保存

save(int saveFlags)

API26弃用

画布状态还原

restore()

--

画布状态还原

restore(int saveCount)

--

为什么要有画布快照这个功能?这个功能有什么用?

如果大家已经试过位移、旋转等操作,你们有可能发现,如果我连续两次进行操作,第一次画布旋转 90 绘制一个矩形,第二次画布旋转 180 绘制一个矩形。得到的结果是这样的:

效果图-g.png

我们发现第二次旋转 180 绘制的图形,实际上旋转了 270。这是因为我们所有的操作是叠加的,并不会自动归位。这样对于简单操作来说,还是可以的,但是如果操作方式变得比较复杂,无疑会增加我们的工作量。

所以,我们需要屏幕快照来保存当前画布的状态,当绘制完成后,返回到原来的画布状态。

canvas.translate(originX,originY);

RectF rectF = new RectF(0, 0, 200, 200);

mRectPaint.setColor(Color.BLACK);

canvas.drawRect(rectF,mRectPaint);

canvas.save();

mRectPaint.setColor(Color.RED);

canvas.rotate(90);

canvas.drawRect(rectF,mRectPaint);

canvas.restore();

canvas.save();

mRectPaint.setColor(Color.GREEN);

canvas.rotate(180);

canvas.drawRect(rectF,mRectPaint);

canvas.restore();

效果图-g.png

需要注意的是,我们可以 save 次数大于 restore,但是 restore 的次数不能多于 save 次数,否则会出错。

关于画布操作中的位移、缩放、旋转、错切,其实都是对于 Matric 的封装。如果想了解这方面的东西,可以简单看看下面的文章。希望你的线性代数没有忘光。

谢谢观赏

android里面画布快照,自定义 View - Canvas - 画布操作和快照相关推荐

  1. Android实现雪花特效自定义view

    一.前言 这个冬天,老家一直没有下雨, 正好圣诞节,就想着制作一个下雪的特效. 圣诞祝福:平安夜,舞翩阡.雪花飘,飞满天.心与心,永相伴. 圣诞节是传统的宗教节日,对于基 督徒,那是庆祝耶稣的诞生,纪 ...

  2. Android 气泡动画(自定义View类)

    Android 气泡动画(自定义View类) 一.前言 二.代码 1. 随机移动的气泡 2.热水气泡 一.前言 最近有需求制作一个水壶的气泡动画,首先在网上查找了一番,找到了一个文章. https:/ ...

  3. Android动画特效之自定义View

      Android动画特效之Animator属性动画实现_Angel-杭州的博客-CSDN博客   我在百忙之中抽出宝贵时间来实现Android动画特效,也就是Android Animator动画效果 ...

  4. 【Android】自定义View、画布Canvas与画笔Paint

    安卓自定义View其实很简单.这个View可以像<[Android]利用Java代码布局,按钮添加点击事件>(点击打开链接)一样,利用Java代码生成一系列的组件.也可以配合画布Canva ...

  5. Android 自定义View —— Canvas

    上一篇在android 自定义view Paint 里面 说了几种常见的Point 属性 绘制图形的时候下面总有一个canvas ,Canvas 是是画布 上面可以绘制点,线,正方形,圆,等等,需要和 ...

  6. Android 自定义View Canvas —— Bitmap

    Bitmap 绘制图片 常用的方法有一下几种 (1) drawBitmap(@NonNull Bitmap bitmap, float left, float top, @Nullable Paint ...

  7. android canvas 手写,自定义view—Canvas实现手写板和涂鸦功能

    学习导航 第一节:http://blog..net/bobo8945510/article/details/53197727 -自定义View-自定义属性及引用 第二节:http://blog..ne ...

  8. Android Matrix手势缩放自定义view 不止于Imageview

    转载请注明出处:http://blog.csdn.net/coderyue/article/details/51397409 之前写过一篇文章Android TextView 横竖排切换(字方向不变) ...

  9. android 声波曲线动画,(自定义view实现)音量波形图

    标签: 自定义view 音量波形 音波 本文目的:主要是记录自己在实现自定义view的时候,一些思路和解决方案. 目标 音量波形图 绘制两个音量波形,并且能够向右运动,上面的波形移动速度慢,下面的波形 ...

最新文章

  1. zabbix系列之邮件告警(三)
  2. javascript 死循环
  3. 研究人员利用脑电ErrP信号实时控制机器人
  4. 单元测试之更强大的powermock
  5. MegaCli 监控Raid状态
  6. Android 图形驱动初始化(二十三)
  7. linux命令-p,Linux-send命令详解
  8. selenium自动化测试配置工具整理
  9. Atitit 核心代码包括哪些 重要部分 压缩 分类 图像处理部分 爬虫 分词检索部分 多媒体 基础设施代码 非功能性 类库框架 源到源的语言翻译 跨语言集成 互操作通讯 算
  10. 编程 常用3500汉字 常用字符
  11. Power Query M语言全部list函数,快速分类掌握
  12. 视频教程-Qt语言从入门到精通-C/C++
  13. 车载视频监控基于JTT808/1078管理平台商业开源
  14. C语言常见文件操作函数总结详解
  15. mysql为什么要用b+树
  16. 6.4_[Java 数组]-详解 break/continue 跳转语句
  17. 小米6微信无法连接网络连接到服务器,如何修复小米手机上的无法连接到网络错误...
  18. zzulioj1873: This offer 深搜
  19. ① 尚品汇的后台管理系统【尚硅谷】【Vue】
  20. WORD保存文件时,内存不足,是否存为挽救文档

热门文章

  1. postgresql pgsql登录及创建用户
  2. goroutine sync.RWMutex读写锁RLock的使用
  3. Linux安全技术和防火墙介绍
  4. 解决 Ubuntu 18.04 无法关机的问题
  5. JavaFX控制器:设置按钮点击事件代码示例
  6. Spark RDD并行度与分区设置
  7. Scala中Unit 类型、Null 类型和 Nothing 类型
  8. Python Django 自定义Manager重写objects.create()方法代码示例
  9. 服务器2012r2系统安装数据库,数据库图文详解Windows Server2012 R2中安装SQL Server2008...
  10. 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(五)