티스토리 뷰

페인트보드 구현중 Canvas객체의 save메소드와 restore메소드가 하는 역할이 무엇인지 궁금해서 찾아 보았다.

역시 개발자의 참고서라고 할 수 있는 스택오버플로우에 자세히 설명 되어 있어서 가져왔다.


Even when I first answered this question a few years ago, I didn't really understand how Canvastransforms (like translaterotate, etc.) worked. I used to think that translate moved the thing that you were drawing. Actually, translate moves the entire coordinate system. This has the desired effect of also moving the thing you are drawing.

On your screen it looks like you are moving the drawing:

-> translate또는 rotate와 같은 캔버스 자체를 변경시키는 메소드의 효과를 저장하는것이 canvas.save()메소드이고 그 효과를 save한 상태로 되돌리는것이 restore()이다. translate란 그림 자체를 다른 위치로 옮기는 효과가 아니라 캔버스 자체를 움직이는 효과이다. 즉 좌표계 자체가 움직인다. 아래 예시를 보자.

Android Canvas.translate() method

What is actually happening is you are moving the coordinate system to a new place on the canvas:

canvas의 translate메소드는 좌표계 자체를 움직인다. 그림의 좌표를 움직인게 아니라, 좌표계를 바꿨기 때문에 그림이 움직인것이다.

enter image description here

I draw the tree first at (0,0). Then I translate the origin of the coordinate system to some other spot on the canvas. Then I draw the tree again at (0,0). This way my drawing code doesn't have to change anything at all. Only the coordinate system changes.

Normally (0,0) is at the top left of your view. Doing Canvas.translate moves it to some other part of your view.

-> 처음 나는 트리를 (0,0)위치에 그렸다. 그리고나서 원래의 좌표계를 캔버스의 다른 지점으로 translate시켰다. 그리고 트리를 (0,0)위치에 다시 그렸다. 이때 나는 트리를 (0,0)위치에 그렸지만 좌표계가 변경된 상태에서 그렸기 때문에 나의 코드는 변경시키지 않았음에도 다른 위치에 트리 하나를 더 그릴 수 있었다. 

Saving and Restoring the Coordinate System

You can do save() and restore() to get back to your original coordinate system.

// 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 

When you restore, the drawing is already on the canvas. Restoring doesn't change that. It just moves the coordinate system back to wherever it was when you saved it.

즉, save()와 restore()는 canvas의 좌표계를 저장,복구 하는 메소드라고 보면 될것 같다.

먼저 비트맵을 그리고나서 좌표계를 저장한다. 그리고 캔버스의 좌표계를 dx,dy만큼 움직이고 트리를 0,0에 다시 그린다. 그리고 좌표계를 원래 상태로 되돌린다. 이렇게 되면 (0,0)위치와 (dx,dy)위치에 트리 2개가 그려져있을것이다. 좌표계만 예전것으로 돌아가는것이지 그림 자체도 save()시점으로 돌아가지 않는다.

Why Translate

Note that you could achieve the same affect by changing the x,y coordinates of the draw method:

// 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);

This might be more intuitive coming from a math background. However, when you are translating, rotating, and scaling your image, it is often much easy to keep your drawing logic the same and just transform the canvas. Recalculating x and y for every draw could be very expensive.


위와 같이 x,y좌표예 dx, dy만큼 더해서 그림을 다시 그리는게 좀 더 직관적이긴 하다. 하지만, 만약 매우 많은 좌표에 대해서 위와 같은 일을 해야 한다고 해보자. 그때는 위처럼 구현하는것이 translate를 사용해서 구현하는것보다 좀 더 고비용일 수 있다.


따라서 translate와 save restore를 잘 알아두는것이 좋다.


예를들어, 정사각형 하나를 그리고 마름모를 그려야 한다고 했을때, 0,0위치에 정사각형 하나를 그린다음에 캔버스를save시킨다음에 rotate시키고 translate시켜서 (0,0)에 한번더 그리고 난뒤 캔버스를 restore시킨다. 


그럼 정사각형 하나 마름모 하나를 그릴 수 있을 것이다.


댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함