Share via


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 像素的平方區域:

圓形網格線

程序的實例建構函式會使用 處理程式建立 SKCanvasViewPaintSurface ,這個處理程式會用來 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具有這些整數陣列參數的方法似乎無法運作。 具有 DrawBitmapLatticeSKLattice 別參數的方法可以運作,而這就是下面所示範例中使用的方法。

結構 SKLattice 會定義四個屬性:

  • XDivs,整數陣列
  • YDivs,整數陣列
  • Flags、的 SKLatticeFlags陣列、列舉型別
  • BoundsNullable<SKRectI> 別為 ,以指定位圖內的選擇性來源矩形

數位陣圖 XDivs 的寬度分割成垂直帶狀。 第一個等量從左邊的像素 0 延伸至 XDivs[0]。 此帶狀以像素寬度呈現。 第二個等量從 延伸 XDivs[0]XDivs[1],並且會延展。 第三個等量從 延伸 XDivs[1]XDivs[2] ,並以像素寬度呈現。 最後一個等量從陣列的最後一個專案延伸至點陣圖的右邊緣。 如果陣列有偶數個元素,則會以像素寬度顯示。 否則會伸展。 垂直帶狀帶的總數是陣列中元素數目的一個以上。

陣列 YDivs 很類似。 它會將數位的高度分割成水準帶狀。

XDivsYDivs 陣陣會將點陣圖分割成矩形。 矩形數目等於水平帶數和垂直帶數的乘積。

根據 Skia 檔, Flags 陣列包含每個矩形的一個專案、第一個矩形的頂端數據列、第二列等等。 Flags陣列的類型為SKLatticeFlags,具有下列成員的列舉:

  • Default 值為 0
  • Transparent 值為 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);
    }
}

XDivsYDivs 屬性都設定為只有兩個整數的陣列,將點陣圖分成水準和垂直三條線:從圖元 0 到圖元 100(以圖元大小轉譯)、從圖元 100 到圖元 400(延展),以及從圖元 400 到圖元 500 像素(圖元大小)。 一起, XDivsYDivs 定義總共9個矩形,也就是陣列的大小 Flags 。 只要建立陣列就足以建立值的陣列 SKLatticeFlags.Default

顯示器與上一個程式相同:

Lattice Nine-Patch

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

XDivsYDivs 陣列有些不同,導致顯示與先前的範例不一樣對稱:

Lattice Display

在左側的 iOS 和 Android 影像中,只有較小的圓形會以圖元大小呈現。 其他一切都被伸展。

Lattice Display 頁面會將陣列的Flags建立一般化,讓您能夠更輕鬆地進行實驗XDivsYDivs 特別是,您會想要查看當您將 或 YDivs 陣列的第一個項目XDivs設定為0時會發生什麼情況。