픽셀 및 디바이스 독립적 단위
SkiaSharp 좌표와 Xamarin.Forms 좌표의 차이점 살펴보기
이 문서에서는 SkiaSharp 및 Xamarin.Forms에서 사용되는 좌표계의 차이점을 살펴봅니다. 두 좌표계 간에 변환하는 정보를 얻고 특정 영역을 채우는 그래픽을 그릴 수도 있습니다.
한동안 프로그래밍을 Xamarin.Forms 했다면 좌표와 크기에 대한 Xamarin.Forms 느낌이 들 수 있습니다. 이전 두 문서에서 그린 원은 약간 작게 보일 수 있습니다.
이러한 원 은 크기와 비교하여 Xamarin.Forms 작습니다. 기본적으로 SkiaSharp는 픽셀 단위로 그리는 반면 Xamarin.Forms 기본 플랫폼에 의해 설정된 디바이스 독립적 단위에서 기본 좌표 및 크기를 그립니다. 좌표계에 대한 Xamarin.Forms 자세한 내용은 5장에서 확인할 수 있습니다. 를 사용하여 Mobile Apps를 만드는 책의 크기 처리 Xamarin.Forms
Surface Size라는 샘플 프로그램의 페이지는 SkiaSharp 텍스트 출력을 사용하여 세 가지 소스의 디스플레이 화면 크기를 표시합니다.
- 개체의 기본 Xamarin.Forms
Width
및Height
속성입니다SKCanvasView
. CanvasSize
개체의SKCanvasView
속성입니다.Size
이전 두 페이지에 사용된 속성과Height
일치하는Width
값의 속성SKImageInfo
입니다.
클래스는 SurfaceSizePage
이러한 값을 표시하는 방법을 보여줍니다. 생성자는 개체를 SKCanvasView
필드로 저장하므로 이벤트 처리기에서 PaintSurface
액세스할 수 있습니다.
SKCanvasView canvasView;
public SurfaceSizePage()
{
Title = "Surface Size";
canvasView = new SKCanvasView();
canvasView.PaintSurface += OnCanvasViewPaintSurface;
Content = canvasView;
}
SKCanvas
에는 6개의 다른 DrawText
메서드가 포함되어 있지만 이 DrawText
메서드는 가장 간단합니다.
public void DrawText (String text, Single x, Single y, SKPaint paint)
텍스트 문자열, 텍스트가 시작되는 X 및 Y 좌표 및 개체를 SKPaint
지정합니다. X 좌표는 텍스트의 왼쪽 위치를 지정하지만 주의해야 합니다. Y 좌표는 텍스트 기준선의 위치를 지정합니다. 줄 지어 있는 종이에 손으로 작성한 적이 있는 경우 기준선은 문자가 앉는 선이며, 아래의 하위 항목(예: g, p, q 및 y 문자의 하위 항목)입니다.
개체 SKPaint
를 사용하면 텍스트 색, 글꼴 패밀리 및 텍스트 크기를 지정할 수 있습니다. 기본적으로 TextSize
이 속성의 값은 12이며, 이로 인해 휴대폰과 같은 고해상도 디바이스에서 작은 텍스트가 생성됩니다. 가장 간단한 애플리케이션 외에는 표시할 텍스트의 크기에 대한 정보도 필요합니다. 클래스는 SKPaint
속성과 여러 MeasureText
메서드를 FontMetrics
정의하지만 덜 멋진 요구 사항을 FontSpacing
위해 속성은 연속 텍스트 줄 간격을 지정하는 데 권장되는 값을 제공합니다.
다음 PaintSurface
처리기는 40픽셀의 개체 TextSize
를 만듭니다SKPaint
. 이 개체는 오름차순 위쪽에서 하위 항목의 아래쪽까지 텍스트의 원하는 세로 높이입니다. FontSpacing
개체가 SKPaint
반환하는 값은 약 47픽셀보다 약간 큽니다.
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
SKPaint paint = new SKPaint
{
Color = SKColors.Black,
TextSize = 40
};
float fontSpacing = paint.FontSpacing;
float x = 20; // left margin
float y = fontSpacing; // first baseline
float indent = 100;
canvas.DrawText("SKCanvasView Height and Width:", x, y, paint);
y += fontSpacing;
canvas.DrawText(String.Format("{0:F2} x {1:F2}",
canvasView.Width, canvasView.Height),
x + indent, y, paint);
y += fontSpacing * 2;
canvas.DrawText("SKCanvasView CanvasSize:", x, y, paint);
y += fontSpacing;
canvas.DrawText(canvasView.CanvasSize.ToString(), x + indent, y, paint);
y += fontSpacing * 2;
canvas.DrawText("SKImageInfo Size:", x, y, paint);
y += fontSpacing;
canvas.DrawText(info.Size.ToString(), x + indent, y, paint);
}
이 메서드는 X 좌표 20(왼쪽에 약간의 여백)과 Y 좌표를 사용하여 텍스트의 fontSpacing
첫 번째 줄을 시작합니다. 이 좌표는 표시 화면 맨 위에 있는 첫 번째 텍스트 줄의 전체 높이를 표시하는 데 필요한 것보다 약간 더 큽니다. 호출할 DrawText
때마다 Y 좌표가 1~2씩 증가합니다 fontSpacing
.
실행 중인 프로그램은 다음과 같습니다.
볼 CanvasSize
수 있듯이 값의 SKCanvasView
속성과 Size
속성 SKImageInfo
은 픽셀 차원을 보고할 때 일관성이 있습니다. 속성 및 Width
속성 SKCanvasView
은 Height
Xamarin.Forms 속성이며 플랫폼에서 정의한 디바이스 독립적 단위로 보기의 크기를 보고합니다.
왼쪽의 iOS 7 시뮬레이터에는 디바이스 독립적 단위당 2픽셀이 있고 중앙의 Android Nexus 5에는 단위당 3픽셀이 있습니다. 따라서 앞에서 보여 준 간단한 원은 플랫폼에 따라 크기가 다릅니다.
디바이스 독립적 단위로 완전히 작업하려면 해당 속성을 SKCanvasView
true
하여 작업을 수행할 수 있습니다. 그러나 결과가 마음에 들지 않을 수 있습니다. SkiaSharp는 디바이스 독립적 단위의 보기 크기와 동일한 픽셀 크기로 더 작은 디바이스 화면에서 그래픽을 렌더링합니다. 예를 들어 SkiaSharp는 Nexus 5에서 360 x 512 픽셀의 디스플레이 화면을 사용합니다. 그런 다음, 해당 이미지를 크기로 확장하여 눈에 띄는 비트맵 jaggies를 생성합니다.
동일한 이미지 해상도를 유지하기 위해 두 좌표계 간에 변환하는 고유한 간단한 함수를 작성하는 것이 더 좋습니다.
메서드 SKCanvas
외에도 DrawCircle
타원을 그리는 두 가지 DrawOval
메서드를 정의합니다. 타원은 단일 반지름이 아닌 두 개의 반지름으로 정의됩니다. 이러한 반경을 주 반경 및 부 반지름이라고 합니다. 이 메서드는 DrawOval
X 및 Y 축에 두 개의 radii 병렬로 타원을 그립니다. (X 및 Y축과 평행하지 않은 축으로 타원을 그려야 하는 경우 문서에서 설명한 대로 회전 변환을 사용할 수 있습니다.원호를 그리는 세 가지 방법 문서에서 설명한 대로 회전 변환 또는 그래픽 경로). 메서드의 DrawOval
이 오버로드는 두 개의 radii 매개 변수 rx
의 이름을 지정하고 X 및 ry
Y 축과 병렬임을 나타냅니다.
public void DrawOval (Single cx, Single cy, Single rx, Single ry, SKPaint paint)
디스플레이 화면을 채우는 줄임표를 그릴 수 있나요? 타원 채우기 페이지에서 방법을 보여 줍니다. PaintSurface
EllipseFillPage.xaml.cs 클래스의 이벤트 처리기는 전체 줄임표 및 yRadius
디스플레이 화면 내의 윤곽선에 맞게 스트로크 너비 xRadius
의 절반을 뺍니다.
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
float strokeWidth = 50;
float xRadius = (info.Width - strokeWidth) / 2;
float yRadius = (info.Height - strokeWidth) / 2;
SKPaint paint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.Blue,
StrokeWidth = strokeWidth
};
canvas.DrawOval(info.Width / 2, info.Height / 2, xRadius, yRadius, paint);
}
여기서 실행 중입니다.
다른 DrawOval
메서드에는 SKRect
인수가 있는데, 이 사각형은 왼쪽 위 모서리와 오른쪽 아래 모서리의 X 및 Y 좌표를 기준으로 정의됩니다. 타원은 직사각형을 채웁니다. 이는 다음과 같이 타원 채우기 페이지에서 사용할 수 있음을 시사합니다.
SKRect rect = new SKRect(0, 0, info.Width, info.Height);
canvas.DrawOval(rect, paint);
그러나 네 면의 타원 윤곽선 가장자리가 모두 잘립니다. 이 작업을 올바르게 수행하려면 다음을 기준으로 strokeWidth
모든 SKRect
생성자 인수를 조정해야 합니다.
SKRect rect = new SKRect(strokeWidth / 2,
strokeWidth / 2,
info.Width - strokeWidth / 2,
info.Height - strokeWidth / 2);
canvas.DrawOval(rect, paint);