Сегментированные отображение растровых карт SkiaSharp
Объект SkiaSharp SKCanvas
определяет метод с именем DrawBitmapNinePatch
и двумя методами, которые DrawBitmapLattice
очень похожи. Оба этих метода отрисовывают растровое изображение до размера прямоугольника назначения, но вместо равномерного растяжения растрового изображения отображают части растрового изображения в его измерениях пикселей и растягивают другие части растрового изображения, чтобы он соответствовал прямоугольнику:
Эти методы обычно используются для отрисовки растровых изображений, которые образуют часть объектов пользовательского интерфейса, таких как кнопки. При проектировании кнопки обычно требуется, чтобы размер кнопки был основан на содержимом кнопки, но вы, вероятно, хотите, чтобы граница кнопки была одинаковой шириной независимо от содержимого кнопки. Это идеальное применение DrawBitmapNinePatch
.
DrawBitmapNinePatch
это особый случай DrawBitmapLattice
, но это проще двух методов для использования и понимания.
Отображение девяти исправлений
Концептуально делит DrawBitmapNinePatch
растровое изображение на девять прямоугольников:
Прямоугольники в четырех углах отображаются в их размерах пикселей. Как указывают стрелки, другие области на краях растрового изображения растягиваются по горизонтали или по вертикали к области целевого прямоугольника. Прямоугольник в центре растянут как по горизонтали, так и по вертикали.
Если в прямоугольнике назначения недостаточно места, чтобы отобразить даже четыре угла в их измерениях пикселей, они масштабируются до доступного размера, и отображаются только четыре угла.
Чтобы разделить растровое изображение на эти девять прямоугольников, необходимо указать прямоугольник в центре. Это синтаксис 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 пикселей квадрата, и состоит из массива из 25 кругов, каждый из которых занимает 100 пикселей квадратной площади:
Конструктор экземпляра программы создает SKCanvasView
обработчик, который используется DrawBitmapNinePatch
для отображения растрового PaintSurface
изображения, растянутого на всю область отображения:
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 кругов. Круги в углах отображаются в их измерениях пикселей, и все остальное растягивается соответствующим образом:
Страница 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]
и отображается в ширину пикселя. Последняя полоса расширяется от последнего элемента массива к правому краю растрового изображения. Если массив имеет четное количество элементов, он отображается в ширине пикселя. В противном случае это растянуто. Общее число вертикальных полос — это несколько элементов в массиве.
Массив YDivs
аналогичен. Он делит высоту массива на горизонтальные полосы.
Вместе массив XDivs
YDivs
делит растровое изображение на прямоугольники. Число прямоугольников равно продукту числа горизонтальных полос и количеству вертикальных полос.
Согласно документации Skia, Flags
массив содержит один элемент для каждого прямоугольника, сначала верхнюю строку прямоугольников, а затем вторую строку и т. д. Массив Flags
имеет тип SKLatticeFlags
, перечисление со следующими элементами:
Default
со значением 0Transparent
со значением 1
Тем не менее, эти флаги, кажется, не работают, как они должны, и лучше всего игнорировать их. Но не устанавливайте Flags
для свойства значение null
. Задайте для него достаточно большой массив значений SKLatticeFlags
, чтобы охватывать общее количество прямоугольников.
Страница Lattice Nine Patch используется DrawBitmapLattice
для имитации DrawBitmapNinePatch
. Он использует ту же растровую карту, созданную в 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);
}
}
XDivs
YDivs
Оба свойства задаются массивами всего двух целых чисел, разделяя растровое изображение на три полосы как по горизонтали, так и по вертикали: от пикселя 0 до пикселя 100 (отрисовывается в размере пикселя), от пикселя 100 до пикселя 400 (растянутый) и от пикселя 400 до пикселя 500 (размер пикселя). XDivs
Вместе и YDivs
определите в общей сложности 9 прямоугольников, что является размером массиваFlags
. Простое создание массива достаточно для создания массива значений SKLatticeFlags.Default
.
Отображение идентично предыдущей программе:
Страница отображения lattice делит растровое изображение на 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);
}
}
YDivs
И XDivs
массивы несколько отличаются, что приводит к тому, что отображение не совсем так симметрично, как в предыдущих примерах:
В изображениях iOS и Android слева только меньшие круги отображаются в размерах пикселей. Все остальное растянуто.
Страница отображения lattice обобщает создание массива Flags
, что позволяет экспериментировать с XDivs
и YDivs
более легко. В частности, вы хотите увидеть, что происходит при установке первого элемента XDivs
элемента или YDivs
массива в значение 0.