canvas.translate是什么意思?

59

1
对于任何未来仍在检查此内容的人,翻译只会移动画布坐标,而不是您画的任何内容。因此,请先移动,再绘制 :) - Zee
4个回答

100

即使在几年前我第一次回答这个问题时,我也没有真正理解 Canvas 变换(如 translaterotate 等)的工作原理。我曾经认为 translate 移动你正在绘制的东西。实际上,translate 移动了整个坐标系。这样做也会移动你正在绘制的东西。

在你的屏幕上,看起来像是你在移动图形:

Android Canvas.translate() method

实际上,你正在将坐标系移动到画布上的新位置:

enter image description here

我首先在(0,0)处绘制树。然后,我将坐标系的原点平移至画布上的其他位置。然后,我再次在(0,0)处绘制树。这样,我的绘图代码完全不需要改变任何内容,只有坐标系发生了改变。

通常情况下,(0,0)在视图的左上角。通过使用 Canvas.translate,可以将其移动到视图的其他部分。

保存和恢复坐标系

你可以使用 save()restore() 返回到原始的坐标系。

// draw the tree the first time
canvas.drawBitmap(tree, 0, 0, mPaint);

// draw the tree the second time
canvas.save();
canvas.translate(dx, dy); // dx = change in x, dy = change in y
canvas.drawBitmap(tree, 0, 0, mPaint); // draw still thinks it is at (0,0)
canvas.restore(); // undo the translate 

当你进行恢复操作时,绘图已经在画布上了。 恢复操作并不会改变这一点,它只是将坐标系移回保存时的位置。

为什么翻译

请注意,您可以通过更改绘制方法中的x、y坐标来实现相同的效果:

// draw the tree the first time
canvas.drawBitmap(tree, x, y, mPaint);

// update the x,y coordinates
x += dx;
y += dy;

// draw the tree the second time
canvas.drawBitmap(tree, x, y, mPaint);

如果你有数学背景,这可能会更容易理解。然而,在进行图像的翻译、旋转和缩放时,通常更容易保持绘画逻辑不变,只是对画布进行变换。为每次绘制重新计算xy可能非常昂贵。


1
我实际上想知道save()、translate()和restore()都是做什么的。这个回答了我的问题。 - Daniel Viglione

53

想象它是一个打印头。

最简单的解释方法就是想象它是喷墨或2D打印机的打印头。

translate 基本上会沿着X和Y轴移动你告诉它的像素数。

移动后的位置成为新的"原点"(0,0)。

既然我们理解了这一点,让我们通过以下步骤制作一个简单的面孔:

起始原点:

x

x(大致地)表示原点(或打印头)的位置。

为左眼画一个矩形:

canvas.drawRect(10, 10, 10, 10, paint);

x__
|__|

注意: "原点" 没有改变,它仍然位于此矩形的左上角。

将 "原点" 右移 20 点:

canvas.translate(20, 0)

 __    x    
|__|

使用完全相同的矩形命令绘制右眼:

canvas.drawRect(10, 10, 10, 10, paint);

 __    x__
|__|   |__|

将“origin”移回原始的X位置,并在Y轴上向下移动:

canvas.translate(-20, 20) // Positive numbers for the second param is "down" on the y-axis.

 __     __
|__|   |__|

x

然后画上嘴巴,就完成了:

canvas.drawLine( 0, 0, 30, 0, paint ); 
 __     __
|__|   |__|

x___________

现在只需将 "原点" 向下移动 20 点,以展示我们的杰作:

canvas.translate(0, 20)
 __     __
|__|   |__|

___________

x

由于等宽字体的限制,比例不完全精确。:)


这是目前为止最好的解释,现在经过几次绘图,它变得有点复杂了。有没有一种方法可以重置到原点? - Lamar
@Lamar 谢谢。我不确定是否有内置的方法,但您可以手动跟踪它,以便每次使用翻译时更新本地变量以显示“您离起点多远”。然后,如果您想返回到原始起点,您只需使用一个翻译来撤消这些移动。 - Joshua Pinter
是的,那就是我最终做的。感谢您的帮助。 - Lamar
2
我以为你的名字是乔舒亚 打印机 - mallaudin
1
是的。我先读了你的答案,突然想到是打印机的问题。顺便说一句,回答得很好。 - mallaudin
显示剩余3条评论

47

翻译 - 基本上就是按照要求进行操作。只需使用x,y翻译画布即可。如果您想绘制两个对象,其中一个对象只是另一个的平移,例如x2 = x1 + 50对于每个点。 您不必为第二个对象重新进行所有计算,而是可以仅翻译画布并再次绘制相同的对象。 我希望这个示例能帮助到您。


1
我仍然不明白它的作用。你能解释一下为什么要进行翻译、绘制,然后撤销翻译吗? - Vincent
7
假设你有一张画布,想在上面画两棵树和一只小鸟,小鸟在第一棵树的上方。这两棵树在纵向上的坐标相同,但在横向上的坐标不同(例如,一个在50英寸处)。那么你应该怎么做呢?...继续。 - Mojo Risin
17
你将首先画出前三棵树,然后将画布向右平移50英寸(这就是canvas.translate所做的),并画出第二棵树。为了恢复画布的原始位置,您需要再次将其向左移动50英寸。现在,当您绘制鸟时,它将位于第一棵树上方。如果您不还原画布的原始状态,则在平移之后绘制的所有对象都将被平移到另一个位置- 在我们的例子中,鸟将被绘制在第二棵树上方。 - Mojo Risin
4
不用担心。第一次处理这些事情可能会有点困惑,但是一旦你习惯了,事情就变得更简单了。 - Mojo Risin
完全同意,这个解释太棒了!干得好。 - Roy Lee
也许这是一个愚蠢的新手问题,但你能让翻译平滑地逐像素绘制,而不是跳到新位置吗? - SingleWave Games

0

它将改变您的画布位置(除了比例)的x或y 如果我们进行翻译和缩放,那么这是一般术语中的转换


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接