Android의 (2D) 캔버스 드로잉 파이프 라인은 어떻게 서로 맞습니까?
Android의 (2D) Canvas 드로잉 파이프 라인의 구성 요소가 어떻게 결합되는지 더 잘 이해하고 싶습니다.
예를 들어 XferMode , Shader , MaskFilter 및 ColorFilter는 어떻게 상호 작용합니까? 이러한 클래스에 대한 참조 문서는 매우 드물며 Canvas 및 Paint에 대한 문서는 실제로 유용한 설명을 추가하지 않습니다.
또한 고유 색상을 갖는 그리기 작업 (예 : drawBitmap
, 같은 "벡터"프리미티브와 비교 drawRect
)이이 모든 것에 어떻게 부합 하는지 완전히 명확하지 않습니다. 항상 Paint
의 색상을 무시하고 대신 고유 색상을 사용합니까?
나는 또한 다음과 같은 것을 할 수 있다는 사실에 놀랐습니다.
Paint eraser = new Paint();
eraser.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawOval(rectF, eraser);
이것은 타원을 지 웁니다. 이 사실을 알아 차리기 전에 제 정신 모델은 캔버스에 그리기 (개념적으로)가 별도의 "레이어"로 그리고 그 레이어가 페인트의 전송 모드를 사용하여 캔버스의 비트 맵으로 구성된다는 것입니다. 그렇게 간단하다면 CLEAR 는 소스의 알파에 관계없이 항상 색상 (및 알파)을 0으로 설정하므로 위의 코드는 전체 비트 맵 (클리핑 영역 내)을 지울 것 입니다. 따라서 이것은 지우기를 타원으로 제한하기위한 추가적인 마스킹이 있음을 의미합니다.
API 데모를 찾았 지만 각 데모는 "진공 상태에서"작동하며 초점을 맞춘 항목 (예 : XferModes)이 다른 항목 (예 : ColorFilters)과 상호 작용하는 방식을 보여주지 않습니다.
충분한 시간과 노력으로 나는이 조각들이 어떻게 관련되는지를 경험적으로 알아 내거나 소스를 해독 할 수 있었지만, 다른 누군가가 이미이 문제를 해결했거나 더 나은 파이프 라인 / 드로잉 모델에 대한 실제 문서가 있기를 바랍니다. 나는 놓쳤다.
이 질문은 다른 SO 질문에 대한이 답변 의 코드를보고 영감을 받았습니다 .
최신 정보
몇 가지 문서를 둘러 보면서 여기에 관심이있는 많은 것들이 skia 위에있는 꽤 얇은 베니어 인 것처럼 보이므로 도움이 될 몇 가지 skia 문서가있을 수 있습니다. 내가 찾을 수있는 가장 좋은 것은 다음과 같은 문서입니다SkPaint
.
페인트에 할당 할 수있는 6 가지 유형의 효과가 있습니다.
- SkPathEffect-알파 마스크를 생성하기 전에 지오메트리 (경로) 수정 (예 : 대시)
- SkRasterizer-사용자 정의 마스크 레이어 (예 : 그림자) 구성
- SkMaskFilter-색상 화 및 그리기 전 알파 마스크 수정 (예 : 블러, 엠 보스)
- SkShader-예 : 그래디언트 (선형, 방사형, 스윕), 비트 맵 패턴 (클램프, 반복, 미러)
- SkColorFilter-xfermode (예 : 색상 매트릭스)를 적용하기 전에 소스 색상을 수정합니다.
- SkXfermode-예 : 포터-더프 전송 모드, 블렌드 모드
명시 적으로 명시되어 있지는 않지만 여기서 효과의 순서가 파이프 라인에 나타나는 순서라고 생각합니다.
Romain Guy가 말했듯이 "이 질문은 StackOverflow에서 대답하기 어렵습니다." 실제로 완전한 문서는 없었으며 완전한 문서는 여기에 포함 할 수있을 정도로 큽니다.
결국 소스를 읽고 많은 실험을했습니다. 나는 도중에 메모를했고 결국 여기에서 볼 수있는 문서로 바꿨다.
뿐만 아니라이 다이어그램 :
분명히 "비공식적"이므로 일반적인 경고가 적용됩니다.
위의 내용을 바탕으로 일부 "하위 질문"에 대한 답변은 다음과 같습니다.
또한 고유 색상을 갖는 그리기 작업 (예 :
drawBitmap
, 같은 "벡터"프리미티브와 비교drawRect
)이이 모든 것에 어떻게 부합 하는지 완전히 명확하지 않습니다. 항상Paint
의 색상을 무시하고 대신 고유 색상을 사용합니까?
"소스 색상"은 Shader
. 에서는 일시적으로 대체 비는 경우에 사용된다. 다른 경우 에는 단색을 생성하는 a 를 지정 하지 않으면 의 색상이 사용됩니다.drawBitmap
Shader
BitmapShader
ALPHA_8
Bitmap
Shader
Shader
Paint
나는 또한 다음과 같은 것을 할 수 있다는 사실에 놀랐습니다.
Paint eraser = new Paint(); eraser.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); canvas.drawOval(rectF, eraser);
이것은 타원을 지 웁니다. 이 사실을 알아 차리기 전에 제 정신 모델은 캔버스에 그리기 (개념적으로)가 별도의 "레이어"로 그리고 그 레이어가 페인트의 전송 모드를 사용하여 캔버스의 비트 맵으로 구성된다는 것입니다. 그렇게 간단하다면 CLEAR 는 소스의 알파에 관계없이 항상 색상 (및 알파)을 0으로 설정하므로 위의 코드는 전체 비트 맵 (클리핑 영역 내)을 지울 것 입니다. 따라서 이것은 지우기를 타원으로 제한하기위한 추가적인 마스킹이 있음을 의미합니다.
는 XferMode
"소스 색상"(로부터 적용 Shader
) 및 (로부터의 "대상 색상" Canvas
의 Bitmap
). 결과는 래스터 화에서 계산 된 마스크를 사용하여 대상과 혼합됩니다. 자세한 내용은 위 문서의 전송 단계를 참조하십시오.
이 질문은 StackOverflow에서 대답하기 어렵습니다. 그러나 시작하기 전에 모양 (예 : drawRect ())에는 고유 색상이 없습니다. 색상 정보는 항상 Paint 개체에서 가져옵니다.
이것은 타원을 지 웁니다. 이 사실을 알아 차리기 전에는 캔버스에 그리기 (개념 상)가 별도의 "레이어"로 그리고 해당 레이어가 페인트의 전송 모드를 사용하여 캔버스의 비트 맵으로 구성된다는 것이 저의 멘탈 모델이었습니다. 그렇게 간단하다면 CLEAR는 소스의 알파에 관계없이 항상 색상 (및 알파)을 0으로 설정하므로 위의 코드는 전체 비트 맵 (클리핑 영역 내)을 지울 것입니다. 따라서 이것은 지우기를 타원으로 제한하기위한 추가적인 마스킹이 있음을 의미합니다.
Your model is a bit off. The oval is not drawn into a separate layer (unless you call Canvas.saveLayer()), it is drawn directly onto the Canvas' backing bitmap. The Paint's transfer mode is applied to every pixel drawn by the primitive. In this case, only the result of the rasterization of an oval affects the Bitmap. There's no special masking going on, the oval itself is the mask.
Anyhow, here is a simplified view of the pipeline:
- Primitive (rect, oval, path, etc.)
- PathEffect
- Rasterization
- MaskFilter
- Color/Shader/ColorFilter
- Xfermode
(I just saw your update and yes, what you found describes the stages of the pipeline in order.)
The pipeline becomes just a little bit more complicated when using layers (Canvas.saveLayer()), as the pipeline doubles. You first go through the pipeline to render your primitive(s) inside an offscreen bitmap (the layer), and the offscreen bitmap is then applied to the Canvas by going through the pipeline.
SkPathEffect - modifications to the geometry (path) before it generates an alpha mask (e.g. dashing) SkRasterizer - composing custom mask layers (e.g. shadows) SkMaskFilter - modifications to the alpha mask before it is colorized and drawn (e.g. blur) SkShader - e.g. gradients (linear, radial, sweep), bitmap patterns (clamp, repeat, mirror) SkColorFilter - modify the source color(s) before applying the xfermode (e.g. color matrix) SkXfermode - e.g. porter-duff transfermodes, blend modes
'Nice programing' 카테고리의 다른 글
개인 세터 타이프 스크립트? (0) | 2020.12.05 |
---|---|
docker-compose.yml의 명명 된 볼륨에 대한 호스트 경로를 설정하는 방법 (0) | 2020.12.05 |
"직접"가상 호출과 C #의 인터페이스 호출 성능 (0) | 2020.12.05 |
ASP.Net MVC 4 앱을 철저히 단위 테스트 (0) | 2020.12.05 |
unique_ptr로 전달 선언? (0) | 2020.12.05 |