Android canvas.save()与canvas.restore()的使用总结
含义
canvas.save();
画布将当前的状态保存
canvas.restore();
画布取出原来所保存的状态
使用
canvas.save();与canvas.restore();一般结合使用,.save()函数在前,.restore()函数在后,用来保证在这两个函数之间所做的操作不会对原来在canvas上所画图形产生影响。比如下面这张图:
蓝色方块里面有三张图,两张正常画,一张倾斜45度角画
首先,你可以这样画:先画左上角和左下角的两个图,然后将画布倾斜45度角,再去画第三张图,这样是没问题的,代码如下:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//第一张
canvas.drawBitmap(bitmap, 0 , 0 , paint);
//第二张
canvas.drawBitmap(bitmap, 0 , getHeight()- bitmap.getHeight() , paint);
//旋转45
canvas.rotate(45 , getWidth()/2 , getHeight()/2);
//第三张
canvas.drawBitmap(bitmap, getWidth()/2- bitmap.getWidth()/2 , getHeight()/2- bitmap.getHeight()/2 , paint);
}
如果你要是按这样的顺序画:第一张–>倾斜45度的那一张–>第三张
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//第一张
canvas.drawBitmap(bitmap, 0 , 0 , paint);
//旋转45
canvas.rotate(45 , getWidth()/2 , getHeight()/2);
//第二张
canvas.drawBitmap(bitmap, getWidth()/2- bitmap.getWidth()/2 , getHeight()/2- bitmap.getHeight()/2 , paint);
//第三张
canvas.drawBitmap(bitmap, 0 , getHeight()- bitmap.getHeight() , paint);
}
那么结果就变成了这样:

wtf!第三张图为什么出去了,而且它也没有老实的呆在左下角!
我们来看上面的代码:
第一行:画第一张左上角的图
第二行:旋转画布45度
第三行:画第二张倾斜的图
第四行:画第三张左下角的图
看起来是没有什么问题,但是第二行代码将canvas旋转了45度,所以以后再往canvas上画图的时候都是在这个旋转45度的基础上进行的,也就是说整个坐标系旋转了45度,它已经不再是原来水平竖直的坐标系了,所以第三次画的图会出现偏移。那么如何解决?如下:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//第一张
canvas.drawBitmap(bitmap, 0 , 0 , paint);
//保存画布状态
canvas.save();
//旋转45
canvas.rotate(45 , getWidth()/2 , getHeight()/2);
//第二张
canvas.drawBitmap(bitmap, getWidth()/2- bitmap.getWidth()/2 , getHeight()/2- bitmap.getHeight()/2 , paint);
//取出原来保存的状态
canvas.restore();
//第三张
canvas.drawBitmap(bitmap, 0 , getHeight()- bitmap.getHeight() , paint);
}
在你画完第一张图以后,当要开始画倾斜的那一张的时候,因为你要对画布进行角度的旋转,并且你只想让当前的这一张产生倾斜的角度,所以应该在将画布进行旋转之前将原来的状态进行保存,在画完倾斜的图片后将原来的状态取出来再进行后续的操作,那么你刚才旋转画布的操作就不会对你后续产生影响。
Android canvas.save()与canvas.restore()的使用总结的更多相关文章
- Android中canvas.save()和canvas.restore()的使用
自己定义控件时经常遇到重写View的Ondraw()方法,Ondraw()方法经常设计到save()和restore()这两个方法.这两个相互匹配出现的,作用是用来保存画布的状态和取出保存的状态的. ...
- canvas save()和canvas restore()状态的保存和恢复使用方法及实例
canvas.save()用来保存先前状态的 canvas.restore()用来恢复之前保存的状态 注:两种方法必须搭配使用,否则没有效果 <!DOCTYPE html> <htm ...
- 【转】Android Canvas的save(),saveLayer()和restore()浅谈
Android Canvas的save(),saveLayer()和restore()浅谈 时间:2014-12-04 19:35:22 阅读:1445 评论:0 收藏: ...
- Android Canvas的save(),saveLayer()和restore()浅谈
save() saveLayer() restore() 1.在自定义控件当中你onMeasure和onLayout的工作做完成以后就该绘制该控件了,有时候需要自己在控件上添加一些修饰来满足需求 ...
- Android Canvas save和restoreToCount
@Override public void draw(Canvas canvas) { if (mDrawable!=null) { int sc=canvas.save(); if (mAnimat ...
- Canvas中的save方法和restore方法
初学者也许会误认为canvas中save方法是用来保存绘图状态的图形,而restore方法是用来还原之前保存的绘图状态的图形,其实不然. save():保存当前的绘图状态. restore():恢复之 ...
- Android核心分析之二十八Android GDI之Surface&Canvas
Surface&Canvas Canvas为在画布的意思.Android上层的作图几乎都通过Canvas实例来完成,其实Canvas更多是一种接口的包装.drawPaints ,drawPoi ...
- 初识canvas,使用canvas做一个百分比加载进度的动画
canvas作为H5中重要的新增特性,使开发者可以用它来创作各种令人惊叹的作品.先来看一下浏览器对canvas的支持情况. <canvas> 标签定义图形,比如图表和其他图像,我们使用脚本 ...
- 【canvas系列】canvas实现“ 简单的Amaziograph效果”--画对称图
标题很难引人入胜,先放个效果图好了 如果图片吸引不了你,那我觉得也就没啥看的了. demo链接: https://win7killer.github.io/can_demo/demo/draw_rol ...
随机推荐
- easyui datagrid生成序号列formatter
var opts1; $('#datagrid_1').datagrid({ columns: [ [{ field: 'myNo', title: '序号', align: 'center', wi ...
- R3300L运行CoreELEC, EmuELEC和Armbian
R3300L的参数 CPU: S905LRAM: Samsung K4B4G1646E-BCMA 512MB * 2 = 1GBROM: Samsung KLM8G1WEPD-B031 8GB eMM ...
- 如何单独编译Linux内核源码中的驱动为可加载模块?
答: 分为两步: 1. 配置某个驱动为模块(如: CONFIG_RTC_XXX=m) 2. 指定路径并编译, 如编译drivers/rtc中的驱动 make SUBDIRS=drivers/rtc m ...
- java中HashSet对象内的元素的hashCode值不能变化
因为不管是HashMap(或HashTable,还是HashSet),key值是以hashCode值存进去的,加入key值变了,将无法从集合内删除对象,导致内存溢出.
- 一行命令搞定/usr/bin/perl^M: bad interpreter
https://www.cnblogs.com/albertYe/p/8819143.html **************************************************** ...
- Redis 分布式锁的正确实现方式(Java版)[转]
本文来源: https://www.cnblogs.com/linjiqin/p/8003838.html 前言 分布式锁一般有三种实现方式: 数据库乐观锁: 基于Redis的分布式锁: 基于ZooK ...
- 开发日记:Windows进程守护工具
近期,中心应用服务无故关闭.在检查系统和应用程序日志无果后采取了进程守护的方法.测试期内,脚本未出现系统资源占用过多的情况. 使用说明:1.进程守护.vbs 使用时需修改运行周期(10行).守护进程 ...
- 对Dev的GridControl/GridView控件进行分组并展开操作
今天在模块编写中碰到了对表格的分组,特意在这里把它记录下来. 一.背景:Dev14.1.3,GridControl,.NET4.0+C# 二.过程 1.GridControl设计 一共添加4列:在下面 ...
- IntelliJ Idea 常用10款插件(提高开发效率)
出自:https://blog.csdn.net/weixin_41846320/article/details/82697818 插件安装方式: 1.Background Image Plus 这款 ...
- 构建一个java环境的centos系统镜像并上传到阿里云镜像仓库
编辑dockerfile 文件 FROM centos MAINTAINER zhaoweifeng ENV LANG en_US.UTF-8 RUN /bin/cp /usr/share/zonei ...