SkiaSharp 位陣圖的分段顯示
SkiaSharp SKCanvas
物件會定義名為 DrawBitmapNinePatch
的方法,以及兩個非常類似的方法 DrawBitmapLattice
。 這兩種方法都會將點陣圖轉譯為目的矩形的大小,但與其統一延展位圖,而是在點陣圖的圖元維度中顯示點陣圖的部分,並伸展位圖的其他部分,使其符合矩形:
這些方法通常用於轉譯構成使用者介面物件一部分的點陣圖,例如按鈕。 設計按鈕時,通常您希望按鈕的大小以按鈕的內容為基礎,但您可能希望按鈕的框線是相同的寬度,而不論按鈕的內容為何。 這是的理想應用程式 DrawBitmapNinePatch
。
DrawBitmapNinePatch
是的特殊案例 DrawBitmapLattice
,但使用和瞭解這兩種方法比較容易。
九修補程序顯示
在概念上, DrawBitmapNinePatch
將點陣圖分成九個矩形:
四個角落的矩形會以像素大小顯示。 如箭號所示,位圖邊緣的其他區域會水準或垂直延伸至目的地矩形的區域。 中央的矩形會水準和垂直縮放。
如果目的矩形中沒有足夠的空間來顯示其像素維度中的四個角落,則會相應縮小為可用的大小,只顯示四個角落。
若要將點陣圖分成這九個矩形,只需要在中央指定矩形。 這是 方法的 DrawBitmapNinePatch
語法:
canvas.DrawBitmapNinePatch(bitmap, centerRectangle, destRectangle, paint);
中央矩形相對於點陣圖。 它是一個 SKRectI
值(整數版本的 SKRect
),而且所有座標和大小都是以像素為單位。 目的矩形相對於顯示介面。 paint
引數是選擇性的。
範例中的 Nine Patch Display 頁面會先使用靜態建構函式來建立 類型的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
PaintSurface
,這個處理程式會用來 DrawBitmapNinePatch
顯示延伸至整個顯示介面的點陣圖:
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
的寬度分割成垂直帶狀。 第一個等量從左邊的像素 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 Display 頁面會將點陣圖分成 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 影像中,只有較小的圓形會以圖元大小呈現。 其他一切都被伸展。
Lattice Display 頁面會將陣列的Flags
建立一般化,讓您能夠更輕鬆地進行實驗XDivs
YDivs
。 特別是,您會想要查看當您將 或 YDivs
陣列的第一個項目XDivs
設定為0時會發生什麼情況。