다음을 통해 공유


SkiaSharp 비트맵의 분할된 표시

SkiaSharp SKCanvas 개체는 명명된 DrawBitmapNinePatch 메서드와 매우 유사한 두 개의 메서드 DrawBitmapLattice 를 정의합니다. 이러한 두 메서드는 모두 비트맵을 대상 사각형의 크기로 렌더링하지만 비트맵을 균일하게 늘이는 대신 비트맵의 일부를 픽셀 차원으로 표시하고 비트맵의 다른 부분을 스트레치하여 사각형에 맞도록 합니다.

분할된 샘플

이러한 메서드는 일반적으로 단추와 같은 사용자 인터페이스 개체의 일부를 형성하는 비트맵을 렌더링하는 데 사용됩니다. 단추를 디자인할 때는 일반적으로 단추의 크기를 단추의 내용에 따라 지정하려고 하지만 단추의 내용에 관계없이 단추의 테두리가 같은 너비가 되도록 할 수 있습니다. 이는 .의 이상적인 응용 프로그램입니다 DrawBitmapNinePatch.

DrawBitmapNinePatch 는 특별한 경우 DrawBitmapLattice 이지만 사용하고 이해하는 두 가지 방법 중 더 쉽습니다.

9 패치 디스플레이

개념적으로 DrawBitmapNinePatch 비트맵을 9개의 사각형으로 나눕니다.

나인 패치

네 모서리의 사각형은 픽셀 크기로 표시됩니다. 화살표에서 알 수 있듯이 비트맵 가장자리의 다른 영역은 대상 사각형의 영역까지 가로 또는 세로로 뻗어 있습니다. 가운데에 있는 사각형은 가로 및 세로로 늘입니다.

대상 사각형에 픽셀 차원의 네 개의 모서리도 표시할 공간이 충분하지 않은 경우 사용 가능한 크기로 축소되고 네 개의 모서리만 표시됩니다.

비트맵을 이러한 9개의 사각형으로 나누려면 가운데에 사각형을 지정하기만 하면 됩니다. 메서드의 구문은 다음과 같습니다 DrawBitmapNinePatch .

canvas.DrawBitmapNinePatch(bitmap, centerRectangle, destRectangle, paint);

가운데 사각형은 비트맵을 기준으로 합니다. 값 SKRectI (정수 버전 SKRect)이며 모든 좌표와 크기는 픽셀 단위입니다. 대상 사각형은 디스플레이 화면을 기준으로 합니다. paint 인수는 선택적 요소입니다.

샘플의 나인 패치 표시 페이지는 먼저 정적 생성자를 사용하여 다음과 같은 형식 SKBitmap의 공용 정적 속성을 만듭니다.

public partial class NinePatchDisplayPage : ContentPage
{
    static NinePatchDisplayPage()
    {
        using (SKCanvas canvas = new SKCanvas(FiveByFiveBitmap))
        using (SKPaint paint = new SKPaint
        {
            Style = SKPaintStyle.Stroke,
            Color = SKColors.Red,
            StrokeWidth = 10
        })
        {
            for (int x = 50; x < 500; x += 100)
                for (int y = 50; y < 500; y += 100)
                {
                    canvas.DrawCircle(x, y, 40, paint);
                }
        }
    }

    public static SKBitmap FiveByFiveBitmap { get; } = new SKBitmap(500, 500);
    ···
}

이 문서의 다른 두 페이지는 동일한 비트맵을 사용합니다. 비트맵은 500픽셀 정사각형이며 각각 100픽셀 정사각형 영역을 차지하는 25개의 원 배열로 구성됩니다.

원 눈금

프로그램의 인스턴스 생성자는 전체 디스플레이 화면으로 PaintSurface 뻗어 있는 비트맵을 표시하는 데 사용하는 DrawBitmapNinePatch 처리기를 만듭니다SKCanvasView.

public class NinePatchDisplayPage : ContentPage
{
    ···
    public NinePatchDisplayPage()
    {
        Title = "Nine-Patch Display";

        SKCanvasView canvasView = new SKCanvasView();
        canvasView.PaintSurface += OnCanvasViewPaintSurface;
        Content = canvasView;
    }

    void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
    {
        SKImageInfo info = args.Info;
        SKSurface surface = args.Surface;
        SKCanvas canvas = surface.Canvas;

        canvas.Clear();

        SKRectI centerRect = new SKRectI(100, 100, 400, 400);
        canvas.DrawBitmapNinePatch(FiveByFiveBitmap, centerRect, info.Rect);
    }
}

사각형은 centerRect 16개의 원 중앙 배열을 포함합니다. 모서리의 원은 픽셀 차원에 표시되며, 다른 모든 항목은 그에 따라 늘어나게 됩니다.

9개 패치 표시

UWP 페이지는 너비가 500픽셀이므로 위쪽 및 아래쪽 행을 동일한 크기의 일련의 원으로 표시합니다. 그렇지 않으면 모서리에 없는 모든 원은 줄임표를 형성하도록 늘어나게 됩니다.

원과 줄임표의 조합으로 구성된 개체를 이상하게 표시하려면 원의 행과 열이 겹치도록 가운데 사각형을 정의해 보세요.

SKRectI centerRect = new SKRectI(150, 150, 350, 350);

격자 디스플레이

DrawBitmapLattice 메서드는 유사하지만 수평 또는 세로 DrawBitmapNinePatch나누기의 수에 대해 일반화됩니다. 이러한 구분은 픽셀에 해당하는 정수 배열로 정의됩니다.

DrawBitmapLattice 이러한 정수 배열에 대한 매개 변수가 있는 메서드가 작동하지 않는 것 같습니다. DrawBitmapLattice 형식 SKLattice 의 매개 변수가 있는 메서드가 작동하며 아래 표시된 샘플에 사용된 메서드입니다.

구조체는 SKLattice 다음 네 가지 속성을 정의합니다.

  • XDivs, 정수 배열
  • YDivs, 정수 배열
  • Flags, 열거형 형식의 SKLatticeFlags배열
  • Bounds 비트맵 내에서 선택적 원본 사각형을 지정하는 형식 Nullable<SKRectI>

배열은 XDivs 비트맵의 너비를 세로 줄무늬로 나눕니다. 첫 번째 스트립은 왼쪽의 픽셀 0에서 .로 XDivs[0]확장됩니다. 이 스트립은 픽셀 너비로 렌더링됩니다. 두 번째 스트립은 XDivs[0]XDivs[1]확장되며 확장됩니다. 세 번째 스트립은 XDivs[1] 픽셀 너비로 XDivs[2] 확장되고 렌더링됩니다. 마지막 스트립은 배열의 마지막 요소에서 비트맵의 오른쪽 가장자리까지 확장됩니다. 배열에 짝수의 요소가 있는 경우 픽셀 너비로 표시됩니다. 그렇지 않으면 확장됩니다. 세로 줄무늬의 총 수는 배열의 요소 수보다 1개 더 많습니다.

배열은 YDivs 비슷합니다. 배열의 높이를 가로 스트립으로 나눕니다.

함께 배열과 YDivs 배열은 XDivs 비트맵을 사각형으로 나눕니다. 사각형 수는 가로 줄무늬 수와 세로 줄무늬 수의 곱과 같습니다.

Skia 설명서 Flags 에 따르면 배열에는 각 사각형에 대해 하나의 요소, 첫 번째 사각형의 맨 위 행, 두 번째 행 등이 포함됩니다. 배열은 Flags 다음 멤버가 포함된 열거형 형식 SKLatticeFlags입니다.

  • Default 값이 0인 경우
  • Transparent 값이 1인 경우

그러나 이러한 플래그는 예상대로 작동하지 않는 것 같고 이를 무시하는 것이 가장 좋습니다. 그러나 속성을 null.로 설정 Flags 하지 마세요. 총 사각형 수를 포함할 수 있을 만큼 큰 값 배열 SKLatticeFlags 로 설정합니다.

격자 나인 패치 페이지는 모방DrawBitmapNinePatch하는 데 사용합니다DrawBitmapLattice. 다음에서 만든 동일한 비트맵을 사용합니다.NinePatchDisplayPage

public class LatticeNinePatchPage : ContentPage
{
    SKBitmap bitmap = NinePatchDisplayPage.FiveByFiveBitmap;

    public LatticeNinePatchPage ()
    {
        Title = "Lattice Nine-Patch";

        SKCanvasView canvasView = new SKCanvasView();
        canvasView.PaintSurface += OnCanvasViewPaintSurface;
        Content = canvasView;
    }
    `
    void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
    {
        SKImageInfo info = args.Info;
        SKSurface surface = args.Surface;
        SKCanvas canvas = surface.Canvas;

        SKLattice lattice = new SKLattice();
        lattice.XDivs = new int[] { 100, 400 };
        lattice.YDivs = new int[] { 100, 400 };
        lattice.Flags = new SKLatticeFlags[9];

        canvas.DrawBitmapLattice(bitmap, lattice, info.Rect);
    }
}

XDivsYDivs 속성은 모두 두 정수의 배열로 설정되며, 비트맵을 가로 및 세로로 세 개의 스트립(픽셀 0에서 픽셀 크기로 렌더링됨), 픽셀 100에서 픽셀 400(스트레치)까지, 픽셀 400에서 픽셀 500(픽셀 크기)으로 구분합니다. XDivsYDivs 배열의 크기 Flags 인 총 9개의 사각형을 함께 정의합니다. 배열을 만드는 것만으로도 값 배열 SKLatticeFlags.Default 을 만들 수 있습니다.

디스플레이는 이전 프로그램과 동일합니다.

격자 나인 패치

격자 표시 페이지는 비트맵을 16개의 사각형으로 나눕니다.

public class LatticeDisplayPage : ContentPage
{
    SKBitmap bitmap = NinePatchDisplayPage.FiveByFiveBitmap;

    public LatticeDisplayPage()
    {
        Title = "Lattice Display";

        SKCanvasView canvasView = new SKCanvasView();
        canvasView.PaintSurface += OnCanvasViewPaintSurface;
        Content = canvasView;
    }

    void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
    {
        SKImageInfo info = args.Info;
        SKSurface surface = args.Surface;
        SKCanvas canvas = surface.Canvas;

        canvas.Clear();

        SKLattice lattice = new SKLattice();
        lattice.XDivs = new int[] { 100, 200, 400 };
        lattice.YDivs = new int[] { 100, 300, 400 };

        int count = (lattice.XDivs.Length + 1) * (lattice.YDivs.Length + 1);
        lattice.Flags = new SKLatticeFlags[count];

        canvas.DrawBitmapLattice(bitmap, lattice, info.Rect);
    }
}

XDivs 배열과 YDivs 배열은 다소 다르기 때문에 디스플레이가 이전 예제와 대칭적이지 않습니다.

격자 표시

왼쪽의 iOS 및 Android 이미지에서는 작은 원만 픽셀 크기로 렌더링됩니다. 다른 모든 것들이 늘어났습니다.

격자 표시 페이지는 배열 생성 Flags 을 일반화하여 보다 쉽게 실험 XDivsYDivs 할 수 있도록 합니다. 특히 배열의 첫 번째 요소를 XDivsYDivs 0으로 설정하면 어떻게 되는지 확인할 수 있습니다.