SkiaSharp 비트맵의 분할된 된 표시Segmented display of SkiaSharp bitmaps

샘플 다운로드 샘플 다운로드Download Sample Download the sample

SkiaSharp SKCanvas 이라는 메서드를 정의 하는 개체 DrawBitmapNinePatch 및 이라는 두 가지 방법 DrawBitmapLattice 는 매우 비슷합니다.The SkiaSharp SKCanvas object defines a method named DrawBitmapNinePatch and two methods named DrawBitmapLattice that are very similar. 둘 다 이러한 메서드는 대상 사각형의 크기를 비트맵을 렌더링 하지만 비트맵을 균일 하 게 확장 하는 대신 해당 픽셀 크기의 비트맵의 일부를 표시 하며 사각형 맞도록 비트맵의 다른 부분 확장:Both these methods render a bitmap to the size of a destination rectangle, but instead of stretching the bitmap uniformly, they display portions of the bitmap in its pixel dimensions and stretch other parts of the bitmap so that it fits the rectangle:

샘플 분할Segmented Samples

이러한 메서드는 일반적으로 단추와 같은 사용자 인터페이스 개체의 일부가 되 비트맵을 렌더링 하는 데 사용 됩니다.These methods are generally used for rendering bitmaps that form part of user-interface objects such as buttons. 단추를 디자인할 때 일반적으로 단추의 콘텐츠를 기반으로 하는 단추의 크기 싶지만 단추의 테두리 단추의 내용에 관계 없이 동일한 너비를 할 수 있습니다.When designing a button, generally you want the size of a button to be based on the content of the button, but you probably want the button's border to be the same width regardless of the button's content. 이상적인 응용 프로그램에 DrawBitmapNinePatch합니다.That's an ideal application of DrawBitmapNinePatch.

DrawBitmapNinePatch 특수 한 경우 DrawBitmapLattice 이지만 더 쉽게 이해 하 고 사용할 두 가지 방법 중입니다.DrawBitmapNinePatch is a special case of DrawBitmapLattice but it is the easier of the two methods to use and understand.

9-패치 표시The nine-patch display

개념상 DrawBitmapNinePatch 9 사각형으로 비트맵을 분할 합니다.Conceptually, DrawBitmapNinePatch divides a bitmap into nine rectangles:

9 명의 패치Nine Patch

4 개의 모퉁이에 사각형의 픽셀 크기로 표시 됩니다.The rectangles at the four corners are displayed in their pixel sizes. 화살표를 나타내는 비트맵의 가장자리에서 다른 영역의 대상 사각형의 영역을 가로 또는 세로로 확장 됩니다.As the arrows indicate, the other areas on the edges of the bitmap are stretched horizontally or vertically to the area of the destination rectangle. 가로 및 세로로 가운데에 사각형이 늘어납니다.The rectangle in the center is stretched both horizontally and vertically.

대상 사각형의 픽셀 크기의 네 모퉁이 표시할에 충분 한 공간이 없는 경우 사용 가능한 크기를 nothing을 축소 하지만 네 모퉁이 표시 하는 것입니다.If there is not enough space in the destination rectangle to display even the four corners in their pixel dimensions, then they are scaled down to the available size and nothing but the four corners are displayed.

이러한 9 개의 사각형으로 비트맵을 나누는 데은 가운데에 사각형을 지정 하는 데 필요한만 있습니다.To divide a bitmap into these nine rectangles, it is only necessary to specify the rectangle in the center. 구문은 DrawBitmapNinePatch 메서드:This is the syntax of the DrawBitmapNinePatch method:

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

가운데 사각형 비트맵에 상대적입니다.The center rectangle is relative to the bitmap. 것을 SKRectI 값 (정수 버전 SKRect) 모든 좌표 및 크기는 픽셀 단위의입니다.It is an SKRectI value (the integer version of SKRect) and all the coordinates and sizes are in units of pixels. 대상 사각형을 화면에 상대적입니다.The destination rectangle is relative to the display surface. paint 인수는 선택적 요소입니다.The paint argument is optional.

합니다 9 패치 표시 페이지에 SkiaSharpFormsDemos 샘플 형식의 공용 정적 속성을 만들려면 먼저 정적 생성자를 사용 SKBitmap:The Nine Patch Display page in the SkiaSharpFormsDemos sample first uses a static constructor to create a public static property of type 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);
    ···
}

이 문서의 다른 두 페이지는 같은 비트맵을 사용합니다.Two other pages in this article use that same bitmap. 비트맵 500 픽셀 정사각형 하며 구성 되어 25 원의 배열 모두 동일한 크기, 각 100 픽셀 사각형 영역을 차지 합니다.The bitmap is 500 pixels square, and consists of an array of 25 circles, all the same size, each occupying a 100-pixel square area:

표 원Circle Grid

프로그램의 인스턴스 생성자를 만듭니다는 SKCanvasView 사용 하 여는 PaintSurface 사용 하는 처리기 DrawBitmapNinePatch 해당 전체 화면을 채우도록 확장 비트맵을 표시 하려면:The program's instance constructor creates an SKCanvasView with a PaintSurface handler that uses DrawBitmapNinePatch to display the bitmap stretched to its entire display surface:

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 원의 중앙 배열을 포함 합니다.The centerRect rectangle encompasses the central array of 16 circles. 모퉁이에 있는 원을 해당 픽셀 크기, 표시 되 고 그에 따라 늘어나는 나머지:The circles in the corners are displayed in their pixel dimensions, and everything else is stretched accordingly:

9-패치 디스플레이Nine-Patch Display

UWP 페이지 500 픽셀로 발생 하며 따라서 일련의 동일한 크기의 원 위쪽과 아래쪽 행이 표시 됩니다.The UWP page happens to be 500 pixels wide, and hence displays the top and bottom rows as a series of circles of the same size. 이 고, 그렇지 모퉁이에 있지 않은 모든 분야는 폼 줄임표를 채우도록 확장 합니다.Otherwise, all the circles that are not in the corners are stretched to form ellipses.

이상 하 게 표시 되는 원과 타원의 조합으로 구성 된 개체의 행과 열을 원 겹치도록 가운데 사각형을 정의 하세요.For a strange display of objects consisting of a combination of circles and ellipses, try defining the center rectangle so that it overlaps rows and columns of circles:

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

격자 표시The lattice display

DrawBitmapLattice 메서드는 비슷합니다 DrawBitmapNinePatch, 하지만 모든 가로 또는 세로 구역 수에 대 한 일반화 되어 있습니다.The two DrawBitmapLattice methods are similar to DrawBitmapNinePatch, but they are generalized for any number of horizontal or vertical divisions. 이러한 부서 픽셀에 해당 하는 정수 배열에서 정의 됩니다.These divisions are defined by arrays of integers corresponding to pixels.

합니다 DrawBitmapLattice 정수의 이러한 배열에 대 한 메서드 매개 변수를 사용 하 여 작동 하지 않는 것입니다.The DrawBitmapLattice method with parameters for these arrays of integers does not seem to work. 합니다 DrawBitmapLattice 형식의 매개 변수를 사용 하 여 메서드 SKLattice 작동, 아래 샘플에서 사용 하는 것입니다.The DrawBitmapLattice method with a parameter of type SKLattice does work, and that's the one used in the samples shown below.

합니다 SKLattice 구조 네 가지 속성을 정의 합니다.The SKLattice structure defines four properties:

  • XDivs정수 배열XDivs, an array of integers
  • YDivs정수 배열YDivs, an array of integers
  • Flags에서 배열을 SKLatticeFlags, 열거형 형식Flags, an array of SKLatticeFlags, an enumeration type
  • Bounds 형식의 Nullable<SKRectI> 비트맵 내 선택적 원본 영역을 지정 하려면Bounds of type Nullable<SKRectI> to specify an optional source rectangle within the bitmap

XDivs 배열 세로 줄무늬 비트맵의 너비를 나눕니다.The XDivs array divides the width of the bitmap into vertical strips. 첫 번째 줄무늬를 왼쪽에 0 픽셀에서 확장 XDivs[0]합니다.The first strip extends from pixel 0 at the left to XDivs[0]. 이 줄은 픽셀 너비에 렌더링 됩니다.This strip is rendered in its pixel width. 두 번째 줄에서 확장 XDivs[0]XDivs[1]를 채우도록 확장 되 고 합니다.The second strip extends from XDivs[0] to XDivs[1], and is stretched. 세 번째 줄에서 확장 XDivs[1]XDivs[2] 픽셀 너비에서 렌더링 됩니다.The third strip extends from XDivs[1] to XDivs[2] and is rendered in its pixel width. 마지막 줄 비트맵의 오른쪽 가장자리에서 배열의 마지막 요소까지 확장 됩니다.The last strip extends from the last element of the array to the right edge of the bitmap. 배열의 요소 수는 짝수가 있으면 해당 픽셀 너비에서 표시 됩니다.If the array has an even number of elements, then it's displayed in its pixel width. 그렇지 않으면 해당 연장 됩니다.Otherwise, it's stretched. 세로 줄무늬의 총 수는 하나는 배열의 요소 수를 초과 합니다.The total number of vertical strips is one more than the number of elements in the array.

YDivs 배열 비슷합니다.The YDivs array is similar. 가로 줄무늬를 배열의 높이 나눕니다.It divides the height of the array into horizontal strips.

함께 합니다 XDivsYDivs 배열 사각형으로 비트맵을 나눕니다.Together, the XDivs and YDivs array divide the bitmap into rectangles. 사각형의 수 세로 줄무늬의 수와 가로 스트립의 수를 곱한 하는 것과 같습니다.The number of rectangles is equal to the product of the number of horizontal strips and the number of vertical strips.

Skia 설명서에 따르면는 Flags 배열 요소를 포함 한 각 사각형에 대 한 처음 사각형의 맨 위 행을 두 번째 행 등입니다.According to Skia documentation, the Flags array contains one element for each rectangle, first the top row of rectangles, then the second row, and so forth. 합니다 Flags 형식의 배열이 SKLatticeFlags 를 다음 멤버로 구성 된 열거형:The Flags array is of type SKLatticeFlags, an enumeration with the following members:

  • Default 값이 0 인Default with value 0
  • Transparent 값이 1 인Transparent with value 1

그러나 이러한 플래그 것 같지 않습니다. 작업을 올바른와 무시 하는 것이 좋습니다.However, these flags don't seem to work as they are supposed to, and it's best to ignore them. 설정 하지 않으면 합니다 Flags 속성을 null입니다.But don't set the Flags property to null. 배열에 설정 SKLatticeFlags 값 사각형의 총 수를 포함 하기에 충분 합니다.Set it to an array of SKLatticeFlags values large enough to encompass the total number of rectangles.

합니다 격자 9 패치 사용 하 여 페이지 DrawBitmapLattice 모방 하기 위해 DrawBitmapNinePatch합니다.The Lattice Nine Patch page uses DrawBitmapLattice to mimic DrawBitmapNinePatch. 만든 동일한 비트맵을 사용 하 여 NinePatchDisplayPage:It uses the same bitmap created in 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 픽셀 100 픽셀 (확장) 및 400 픽셀을 선택 하는 픽셀 500 (픽셀 크기).Both the XDivs and YDivs properties are set to arrays of just two integers, dividing the bitmap into three strips both horizontally and vertically: from pixel 0 to pixel 100 (rendered in the pixel size), from pixel 100 to pixel 400 (stretched), and from pixel 400 to pixel 500 (pixel size). 함께 XDivs 하 고 YDivs 9 사각형의 크기는 총 정의의 Flags 배열입니다.Together, XDivs and YDivs define a total of 9 rectangles, which is the size of the Flags array. 배열을 만드는 데 충분는 단순히 배열을 만드는 SKLatticeFlags.Default 값입니다.Simply creating the array is sufficient to create an array of SKLatticeFlags.Default values.

디스플레이 이전 프로그램으로 동일 합니다.The display is identical to the previous program:

9-패치 latticeLattice Nine-Patch

합니다 격자 표시 페이지 16 사각형으로 비트맵을 분할 합니다.The Lattice Display page divides the bitmap into 16 rectangles:

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);
    }
}

합니다 XDivsYDivs 배열은 다르게 표시 하도록 매우 이전 예제와 대칭을 유발 합니다.The XDivs and YDivs arrays are somewhat different, causing the display to be not quite as symmetrical as the previous examples:

표시 격자Lattice Display

IOS 및 Android 이미지 왼쪽에 있는 작은 원만 픽셀 크기로 렌더링 됩니다.In the iOS and Android images on the left, only the smaller circles are rendered in their pixel sizes. 기타 등등 연장 됩니다.Everything else is stretched.

격자 표시 페이지를 만드는 일반화를 Flags 배열에 실험할 수 있습니다 XDivsYDivs 쉽게 합니다.The Lattice Display page generalizes the creation of the Flags array, allowing you to experiment with XDivs and YDivs more easily. 첫 번째 요소를 설정 하면 어떻게 되는지 확인 하려는 특히 합니다 XDivs 또는 YDivs 0으로 배열 합니다.In particular, you'll want to see what happens when you set the first element of the XDivs or YDivs array to 0.