Canvas 및 Surface 개념 이해


114

나는 안드로이드에서 사용되는 SurfaceView전체 Surface/ Canvas/ Bitmap시스템 에 그리는 과정을 이해하는 데 어려움을 겪고 있습니다.

나는 안드로이드 개발자 사이트, 안드로이드 그래픽에 대한 몇 가지 튜토리얼, LunarLander 소스 코드 및 이 질문 에서 찾을 수있는 모든 기사와 API 문서 페이지를 읽었습니다 .

이 진술 중 어떤 것이 사실인지, 그렇지 않은지, 그 이유를 알려주세요.

  1. Canvas그 자체가 Bitmap붙어 있습니다. Surface그 자체가 Canvas붙어 있습니다.
  2. 모든 View창은 동일 Surface하게 공유하므로 동일하게 공유 Canvas됩니다.
  3. SurfaceView의 하위 클래스로 View, 다른 View의 하위 클래스 및 View자체 와 달리 자체적 Surface으로 그릴 수 있습니다.

추가 질문이 하나 있습니다.

  • 비트 맵을 사용하는 고급 작업 Surface이 이미있는 경우 클래스 가 필요한 이유는 무엇입니까? 할 수 있는 일을하기에 부적합한 Canvas상황의 예를 들어주십시오 .CanvasSurface

답변:


223

다음은 몇 가지 정의입니다.

  • Surface는 화면에 합성되는 픽셀을 포함하는 개체입니다. 화면에 표시되는 모든 창 (대화 상자, 전체 화면 활동, 상태 표시 줄)에는 그려지는 고유 한 표면이 있으며 Surface Flinger는이를 올바른 Z 순서로 최종 디스플레이에 렌더링합니다. 표면에는 일반적으로 이중 버퍼링 렌더링을 수행하기 위해 둘 이상의 버퍼 (일반적으로 두 개)가 있습니다. 표면 플린 저가 마지막 버퍼를 사용하여 화면을 합성하는 동안 애플리케이션이 완료 될 때까지 기다릴 필요없이 애플리케이션은 다음 UI 상태를 그릴 수 있습니다. 그림.

  • 창은 기본적으로 바탕 화면의 창을 생각하는 것과 같습니다. 창의 내용이 렌더링되는 단일 표면이 있습니다. 응용 프로그램은 창 관리자와 상호 작용하여 창을 만듭니다. 창 관리자는 각 창에 대한 표면을 생성하고 그리기를 위해 응용 프로그램에 제공합니다. 응용 프로그램은 Surface에서 원하는 것을 그릴 수 있습니다. 창 관리자에게 그것은 단지 불투명 한 직사각형 일뿐입니다.

  • 보기는 창 내부의 대화 형 UI 요소입니다. 창에는 창의 모든 동작을 제공하는 단일 뷰 계층이 연결되어 있습니다. 창을 다시 그려야 할 때마다 (예 : 뷰가 자체적으로 무효화 되었기 때문에) 이것은 창의 표면에서 수행됩니다. Surface가 잠겨 있으며 캔버스를 반환하는 데 사용할 수 있습니다. 그리기 순회는 계층 구조를 따라 수행되며 각 뷰에 대해 Canvas를 전달하여 UI의 일부를 그립니다. 완료되면 Surface가 잠금 해제되고 게시되어 방금 그린 버퍼가 전경으로 스왑 된 다음 Surface Flinger에 의해 화면에 합성됩니다.

  • SurfaceView는 응용 프로그램이 직접 그릴 전용 Surface를 만드는 View의 특수 구현입니다 (일반 뷰 계층 구조 외부, 그렇지 않으면 창에 대한 단일 Surface를 공유해야 함). 작동 방식은 예상보다 간단합니다. SurfaceView가 수행하는 모든 작업은 창 관리자에게 새 창을 만들도록 요청하고 해당 창을 SurfaceView 창 바로 뒤 또는 앞에 Z 순서로 알리고 일치하도록 배치하는 것입니다. 포함하는 창에 SurfaceView가 나타납니다. 표면이 기본 창 뒤에 배치되는 경우 (Z 순서로) SurfaceView는 표면을 볼 수 있도록 기본 창 부분을 투명도로 채 웁니다.

  • 비트 맵은 일부 픽셀 데이터에 대한 인터페이스 일뿐입니다. 픽셀을 직접 만들 때 비트 맵 자체에 의해 픽셀이 할당 될 수도 있고, 그리기를 위해 캔버스를 표면에 연결하는 내부적으로 발생하는 것과 같이 소유하지 않은 픽셀을 가리킬 수도 있습니다. (비트 맵이 생성되고 Surface의 현재 드로잉 버퍼를 가리 킵니다.)

또한 이것이 의미하는 것처럼 SurfaceView는 매우 무거운 개체라는 점을 명심하십시오. 특정 UI에 여러 SurfaceView가있는 경우 중지하고 이것이 정말로 필요한지 생각해보십시오. 두 개 이상 있으면 거의 확실히 너무 많습니다.


대단히 감사합니다! 답변이 더 명확 해졌습니다. 그러나 Canvas를 Surface에 연결하는 부분은 명확하지 않습니다. 그러한 작업이 필요한 곳을 상상할 수 없습니다. 다음은 그 작업의 예가 될 수 있습니다 : 캔버스에 비트 맵 그리기, lockCanvas () 메서드를 사용하여 SurfaceHolder에서 얻은 것?
fyodorananiev 2011 년

1
이것이 드로잉이 일어나는 방식입니다. Canvas는 2D 드로잉 API입니다. o를 표면에 그리려면 Canvas 2d 그리기 API를 사용하여 버퍼를 가리키는 Canvas를 만들어야합니다.
hackbod

6
#hackbod's답변 외에도 객체에 SurfaceView대해 불가능한 보조 스레드에서 렌더링 할 수도 있습니다View
Mohanraj Balasubramaniam

47

창, 표면, 캔버스 및 비트 맵의 ​​개념적 개요

다음은 Window, Surface, Canvas 및 Bitmap간에 상호 작용이 발생하는 방식에 대한 매우 기본적이고 간단한 개념적 개요입니다.
때로는 시각적 표현이 뒤틀린 개념을 이해하는 데 많은 도움이됩니다.
이 그래픽이 누군가를 도울 수 있기를 바랍니다.


4
시각적 이미지 는 텍스트보다 낫습니다 : D
Maveň ツ

18

비트 맵은 단순히 픽셀 모음의 래퍼입니다. 다른 편리한 기능을 가진 픽셀 배열로 생각하십시오.

Canvas는 단순히 모든 그리기 메서드를 포함하는 클래스입니다. 익숙하다면 AWT / Swing의 Graphics 클래스와 비슷합니다. 원이나 상자 등을 그리는 방법에 대한 모든 논리는 Canvas 안에 포함되어 있습니다. 캔버스는 비트 맵 또는 개방형 GL 컨테이너에 그려 지지만 향후 다른 유형의 래스터에 그려 지도록 확장 할 이유가 없습니다.

SurfaceView는 Surface가 포함 된보기입니다. 표면은 비트 맵과 유사합니다 (픽셀 저장소가 있음). 구현 방법은 모르지만 화면 디스플레이와 직접 관련된 항목에 대한 추가 메서드가있는 일종의 비트 맵 래퍼라고 생각합니다 (이는 표면의 이유이며 비트 맵은 너무 일반적입니다). 표면에서 캔버스를 가져올 수 있으며 실제로 기본 비트 맵과 연결된 캔버스를 가져올 수 있습니다.

당신의 질문.

1. 캔버스에는 자체 비트 맵이 첨부되어 있습니다. Surface에는 자체 Canvas가 연결되어 있습니다.

예, 캔버스는 비트 맵 (또는 열린 GL 패널)에서 작동합니다. Surface는 Bitmap 스타일 픽셀 저장소에 사용하는 Surface에서 작동하는 Canvas를 제공합니다.

2. 창의 모든 뷰는 동일한 Surface를 공유하므로 동일한 Canvas를 공유합니다.

아니요. 원하는만큼 표면보기를 가질 수 있습니다.

3. SurfaceView는 View의 하위 클래스로, 다른 View의 하위 클래스 및 View 자체와 달리 그릴 자체 Surface가 있습니다.

예. ListView가 자체 List 데이터 구조를 가진 View의 하위 클래스와 마찬가지로. View의 각 하위 클래스는 다른 작업을 수행합니다.


1
그래서, BitmapSurface픽셀 저장소의 단지 다른 종이며, Canvas그 중 하나 포장 할 수 있습니까?
fyodorananiev 2011 년

2
기본적으로 그렇습니다. Canvas가 표면에 쓸 수 없다는 점을 제외하고는 Surface가 자체 픽셀 저장소로 사용하는 모든 용도에서 작동합니다 (안드로이드 소스를 보지 않고 그것이 무엇인지 확실하게 말할 수 없습니다). Canvas는 Bitmap과 GL에 대한 생성자 만 제공하므로 Bitmap 확장의 일 종일 것입니다.
sksamuel

큰 도움, 감사합니다! 답변 2에 관하여 제 질문에서 저는 SurfaceViews가 아닌 표준 뷰를 의미했습니다. 필드와 버튼이 많은 RelativeLayout이 있다고 가정합니다. 이 경우 Surface가 전체 창에 연결되고 뷰 계층 구조의 모든 뷰에서 공유됩니까?
fyodorananiev 2011 년

1
Surface는 픽셀 모음 일뿐입니다. 따라서 각 표면보기에는 고유 한 표면이 있으며 각보기는 화면의 다른 부분에서 렌더링 될 수 있습니다. 화면을 채울 필요는 없습니다 (전체 화면 게임에서 그래픽을 렌더링하는 일반적인 용도 임에도 불구하고).
sksamuel

1
저는 Bitmap과 Surface가 동등하다고 생각하지 않습니다. Surface는 창 합성자인 Surface Flinger가 알고있는 개체입니다. 즉, 화면에서 직접 볼 수 있고 화면에 Z 순서가 있습니다.
hackbod
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.