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

操作

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);//绘制坐标系

4794f21d514f

效果图-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 的效果图:

4794f21d514f

效果图-g.png

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

4794f21d514f

效果图-g.png

defree 绝对值取值

备注

(1, +∞)

放大

1

不变

(0, 1)

缩小

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

defree 绝对值取值

备注

(1, +∞)

放大

1

不变

(0, 1)

缩小

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

4794f21d514f

效果图-g.png

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

四、错切

操作

API

备注

画布错切

skew(float sx, float sy)

--

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

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

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

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

xResult = x + sy * x

yResult = y + sx * y

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

4794f21d514f

效果图-g.png

五、画布快照

操作

API

备注

画布状态保存

save()

--

画布状态保存

save(int saveFlags)

API26弃用

画布状态还原

restore()

--

画布状态还原

restore(int saveCount)

--

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

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

4794f21d514f

效果图-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();

4794f21d514f

效果图-g.png

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

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

4794f21d514f

谢谢观赏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值