선 및 스트로크 단면
SkiaSharp을 사용하여 다른 스트로크 대문자로 선을 그리는 방법 알아보기
SkiaSharp에서 한 줄 렌더링은 일련의 연결된 직선을 렌더링하는 경우와 매우 다릅니다. 그러나 단일 선을 그리는 경우에도 선에 특정 스트로크 너비를 지정해야 하는 경우가 많습니다. 이러한 선이 넓어짐에 따라 선 끝의 모양도 중요해집니다. 선 끝의 모양을 스트로크 캡이라고 합니다.
단일 선을 SKCanvas
그리는 경우 인수가 개체를 사용하여 줄의 시작 및 끝 좌표를 나타내는 간단한 DrawLine
메서드를 SKPaint
정의합니다.
canvas.DrawLine (x0, y0, x1, y1, paint);
기본적으로 StrokeWidth
새로 인스턴스화된 SKPaint
개체의 속성은 0이며, 두께가 1픽셀인 줄을 렌더링할 때 값 1과 같은 효과를 집니다. 휴대폰과 같은 고해상도 디바이스에서는 매우 얇아서 더 큰 값으로 설정할 StrokeWidth
수 있습니다. 그러나 상당한 두께의 선을 그리기 시작하면 또 다른 문제가 발생합니다. 이러한 두꺼운 선의 시작과 끝을 렌더링하려면 어떻게 해야 하나요?
선의 시작과 끝 모양은 선 캡 또는 Skia에서 스트로크 캡이라고 합니다. 이 컨텍스트의 "cap"이라는 단어는 일종의 모자(줄 끝에 있는 것)를 의미합니다. 개체의 StrokeCap
SKPaint
속성을 열거형의 SKStrokeCap
다음 멤버 중 하나로 설정합니다.
Butt
(기본값)Square
Round
샘플 프로그램에 가장 잘 설명되어 있습니다. 샘플 프로그램의 SkiaSharp 선 및 경로 섹션은 클래스에 StrokeCapsPage
따라 Stroke Caps라는 페이지로 시작합니다. 이 페이지는 열거형의 세 멤버를 반복하여 열거형 멤버의 SKStrokeCap
이름을 모두 표시하고 해당 스트로크 캡을 사용하여 선을 그리는 이벤트 처리기를 정의 PaintSurface
합니다.
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
SKPaint textPaint = new SKPaint
{
Color = SKColors.Black,
TextSize = 75,
TextAlign = SKTextAlign.Center
};
SKPaint thickLinePaint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.Orange,
StrokeWidth = 50
};
SKPaint thinLinePaint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.Black,
StrokeWidth = 2
};
float xText = info.Width / 2;
float xLine1 = 100;
float xLine2 = info.Width - xLine1;
float y = textPaint.FontSpacing;
foreach (SKStrokeCap strokeCap in Enum.GetValues(typeof(SKStrokeCap)))
{
// Display text
canvas.DrawText(strokeCap.ToString(), xText, y, textPaint);
y += textPaint.FontSpacing;
// Display thick line
thickLinePaint.StrokeCap = strokeCap;
canvas.DrawLine(xLine1, y, xLine2, y, thickLinePaint);
// Display thin line
canvas.DrawLine(xLine1, y, xLine2, y, thinLinePaint);
y += 2 * textPaint.FontSpacing;
}
}
열거형의 각 멤버에 SKStrokeCap
대해 처리기는 두 개의 선을 그립니다. 하나는 스트로크 두께가 50픽셀이고 다른 선은 2픽셀의 스트로크 두께로 위쪽에 배치됩니다. 이 두 번째 선은 선 두께 및 스트로크 캡과는 별개로 선의 기하학적 시작과 끝을 설명하기 위한 것입니다.
여기에서 볼 수 있듯이 선 Square
과 스트로크 캡은 줄의 시작 부분과 Round
끝에서 스트로크 너비의 절반만큼 줄 길이를 효과적으로 확장합니다. 이 확장은 렌더링된 그래픽 개체의 차원을 확인해야 하는 경우에 중요합니다.
클래스에는 SKCanvas
다소 특이한 여러 선을 그리는 다른 메서드도 포함되어 있습니다.
DrawPoints (SKPointMode mode, points, paint)
매개 변수는 points
값 배열 SKPoint
이며 mode
세 개의 멤버가 SKPointMode
있는 열거형의 멤버입니다.
Points
개별 지점을 렌더링하려면Lines
각 지점 쌍을 연결하려면Polygon
연속된 모든 지점을 연결하려면
여러 줄 페이지에서는 이 메서드를 보여 줍니다. MultipleLinesPage.xaml 파일은 열거형의 멤버와 열거형의 SKPointMode
멤버 SKStrokeCap
를 선택할 수 있는 두 개의 Picker
보기를 인스턴스화합니다.
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:skia="clr-namespace:SkiaSharp;assembly=SkiaSharp"
xmlns:skiaforms="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms"
x:Class="SkiaSharpFormsDemos.Paths.MultipleLinesPage"
Title="Multiple Lines">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Picker x:Name="pointModePicker"
Title="Point Mode"
Grid.Row="0"
Grid.Column="0"
SelectedIndexChanged="OnPickerSelectedIndexChanged">
<Picker.ItemsSource>
<x:Array Type="{x:Type skia:SKPointMode}">
<x:Static Member="skia:SKPointMode.Points" />
<x:Static Member="skia:SKPointMode.Lines" />
<x:Static Member="skia:SKPointMode.Polygon" />
</x:Array>
</Picker.ItemsSource>
<Picker.SelectedIndex>
0
</Picker.SelectedIndex>
</Picker>
<Picker x:Name="strokeCapPicker"
Title="Stroke Cap"
Grid.Row="0"
Grid.Column="1"
SelectedIndexChanged="OnPickerSelectedIndexChanged">
<Picker.ItemsSource>
<x:Array Type="{x:Type skia:SKStrokeCap}">
<x:Static Member="skia:SKStrokeCap.Butt" />
<x:Static Member="skia:SKStrokeCap.Round" />
<x:Static Member="skia:SKStrokeCap.Square" />
</x:Array>
</Picker.ItemsSource>
<Picker.SelectedIndex>
0
</Picker.SelectedIndex>
</Picker>
<skiaforms:SKCanvasView x:Name="canvasView"
PaintSurface="OnCanvasViewPaintSurface"
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2" />
</Grid>
</ContentPage>
스키아샤프 네임스페이스 선언은 네임스페이스가 및 SKStrokeCap
열거형의 SKPointMode
멤버를 참조하는 데 필요하기 때문에 SkiaSharp
약간 다릅니다. SelectedIndexChanged
두 Picker
뷰에 대한 처리기는 개체를 SKCanvasView
무효화합니다.
void OnPickerSelectedIndexChanged(object sender, EventArgs args)
{
if (canvasView != null)
{
canvasView.InvalidateSurface();
}
}
이 처리기는 XAML 파일에서 SKCanvasView
속성 Picker
이 0으로 설정되고 인스턴스화되기 전에 SKCanvasView
발생할 때 SelectedIndex
이벤트 처리기가 먼저 호출되기 때문에 개체의 존재 여부에 대해 검사 합니다.
PaintSurface
처리기는 뷰에서 Picker
다음 두 열거형 값을 가져옵니다.
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
// Create an array of points scattered through the page
SKPoint[] points = new SKPoint[10];
for (int i = 0; i < 2; i++)
{
float x = (0.1f + 0.8f * i) * info.Width;
for (int j = 0; j < 5; j++)
{
float y = (0.1f + 0.2f * j) * info.Height;
points[2 * j + i] = new SKPoint(x, y);
}
}
SKPaint paint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.DarkOrchid,
StrokeWidth = 50,
StrokeCap = (SKStrokeCap)strokeCapPicker.SelectedItem
};
// Render the points by calling DrawPoints
SKPointMode pointMode = (SKPointMode)pointModePicker.SelectedItem;
canvas.DrawPoints(pointMode, points, paint);
}
스크린샷은 다음과 같은 다양한 Picker
선택 항목을 보여 줍니다.
왼쪽의 i전화 열거형 멤버 DrawPoints
가 선 캡 Square
Butt
이 있는 경우 배열의 각 점을 SKPoint
사각형으로 렌더링하는 방법을 SKPointMode.Points
보여 줌 선 캡이면 원이 렌더링됩니다 Round
.
Android 스크린샷은 .SKPointMode.Lines
이 경우 Round
메서드는 DrawPoints
지정된 줄 바꿈을 사용하여 각 값 쌍 SKPoint
사이에 선을 그립니다.
대신 사용하는 SKPointMode.Polygon
경우 배열의 연속된 점 사이에 선이 그려지지만 매우 자세히 보면 이러한 선이 연결되지 않은 것을 볼 수 있습니다. 이러한 각 개별 줄은 지정된 줄 바꿈으로 시작되고 끝납니다. 대문자를 Round
선택하면 선이 연결된 것처럼 보일 수 있지만 실제로 연결되지는 않습니다.
선이 연결되어 있는지 여부는 그래픽 경로 작업의 중요한 측면입니다.