Udostępnij za pośrednictwem


Segmentowany wyświetlacz map bitowych SkiaSharp

Obiekt SkiaSharp SKCanvas definiuje metodę o nazwie i dwie metody o nazwie DrawBitmapNinePatch DrawBitmapLattice , które są bardzo podobne. Obie te metody renderują mapę bitową do rozmiaru prostokąta docelowego, ale zamiast rozciągnąć mapę bitową równomiernie, wyświetlają fragmenty mapy bitowej w wymiarach pikseli i rozciągają inne części mapy bitowej tak, aby pasowała do prostokąta:

Przykłady segmentowane

Te metody są zwykle używane do renderowania map bitowych, które stanowią część obiektów interfejsu użytkownika, takich jak przyciski. Podczas projektowania przycisku zazwyczaj chcesz, aby rozmiar przycisku był oparty na zawartości przycisku, ale prawdopodobnie chcesz, aby obramowanie przycisku było takie same, niezależnie od zawartości przycisku. Jest to idealne zastosowanie elementu DrawBitmapNinePatch.

DrawBitmapNinePatch Jest to szczególny przypadek, DrawBitmapLattice ale jest to łatwiejsze w użyciu i zrozumieniu tych dwóch metod.

Wyświetlacz z dziewięcioma poprawkami

Koncepcyjnie DrawBitmapNinePatch mapa bitowa dzieli się na dziewięć prostokątów:

Dziewięć poprawek

Prostokąty w czterech rogach są wyświetlane w rozmiarach pikseli. Jak wskazują strzałki, inne obszary na krawędziach mapy bitowej są rozciągnięte w poziomie lub pionowo do obszaru prostokąta docelowego. Prostokąt w środku jest rozciągany zarówno w poziomie, jak i w pionie.

Jeśli w prostokątze docelowym nie ma wystarczającej ilości miejsca, aby wyświetlić nawet cztery narożniki w wymiarach pikseli, zostaną one przeskalowane w dół do dostępnego rozmiaru i nie są wyświetlane żadne narożniki.

Aby podzielić mapę bitową na te dziewięć prostokątów, wystarczy określić prostokąt w środku. Jest to składnia DrawBitmapNinePatch metody:

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

Prostokąt środkowy jest względny względem mapy bitowej. Jest to SKRectI wartość (wersja SKRectcałkowita ) i wszystkie współrzędne i rozmiary znajdują się w jednostkach pikseli. Prostokąt docelowy jest powiązany z powierzchnią wyświetlaną. Argument paint jest opcjonalny.

Strona Wyświetlania dziewięciu poprawek w przykładzie najpierw używa konstruktora statycznego do utworzenia publicznej właściwości statycznej typu 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);
    ···
}

Dwie inne strony w tym artykule używają tej samej mapy bitowej. Mapa bitowa ma 500 pikseli kwadratu i składa się z tablicy składającej się z 25 okręgów o tym samym rozmiarze, z których każdy zajmuje obszar kwadratowy o rozmiarze 100 pikseli:

Siatka okręgowa

Konstruktor wystąpienia programu tworzy SKCanvasView obiekt z procedurą obsługi używaną DrawBitmapNinePatch do wyświetlania mapy bitowej rozciągniętej PaintSurface na całą powierzchnię wyświetlania:

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

Prostokąt centerRect obejmuje centralną tablicę 16 okręgów. Okręgi w rogach są wyświetlane w wymiarach pikseli, a wszystko inne jest odpowiednio rozciągnięte:

Wyświetlanie dziewięciu poprawek

Strona platformy uniwersalnej systemu Windows ma szerokość 500 pikseli, dlatego wyświetla górne i dolne wiersze jako serię okręgów o tym samym rozmiarze. W przeciwnym razie wszystkie okręgi, które nie znajdują się w rogach, są rozciągane w celu utworzenia wielokropka.

W przypadku dziwnego wyświetlania obiektów składających się z kombinacji okręgów i wielokropka spróbuj zdefiniować prostokąt środkowy tak, aby nakładał się na wiersze i kolumny okręgów:

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

Ekran trzaśniaka

Dwie DrawBitmapLattice metody są podobne do DrawBitmapNinePatchmetody , ale są uogólnione dla dowolnej liczby podziałów poziomych lub pionowych. Te podziały są definiowane przez tablice liczb całkowitych odpowiadających pikselom.

Metoda DrawBitmapLattice z parametrami dla tych tablic liczb całkowitych nie wydaje się działać. Metoda DrawBitmapLattice z parametrem typu SKLattice działa i jest używana w poniższych przykładach.

Struktura SKLattice definiuje cztery właściwości:

  • XDivs, tablica liczb całkowitych
  • YDivs, tablica liczb całkowitych
  • Flags, tablica typu SKLatticeFlagswyliczenia
  • Bounds typu Nullable<SKRectI> w celu określenia opcjonalnego prostokąta źródłowego w mapie bitowej

Tablica XDivs dzieli szerokość mapy bitowej na pionowe paski. Pierwszy pasek rozciąga się od piksela 0 po lewej stronie do XDivs[0]. Ten pasek jest renderowany w szerokości pikseli. Drugi pasek rozciąga się od XDivs[0] do XDivs[1], i jest rozciągnięty. Trzeci pasek rozciąga się od XDivs[1] do XDivs[2] i jest renderowany w szerokości pikseli. Ostatni pasek rozciąga się od ostatniego elementu tablicy do prawej krawędzi mapy bitowej. Jeśli tablica ma parzystą liczbę elementów, jest ona wyświetlana w szerokości pikseli. W przeciwnym razie jest rozproszony. Całkowita liczba pasków pionowych jest większa niż liczba elementów w tablicy.

Tablica jest podobna YDivs . Dzieli wysokość tablicy na paski poziome.

Razem tablica XDivs i YDivs dzieli mapę bitową na prostokąty. Liczba prostokątów jest równa iloczynowi liczby poziomych pasków i liczby pasków pionowych.

Zgodnie z dokumentacją Skia tablica Flags zawiera jeden element dla każdego prostokąta, najpierw górny wiersz prostokątów, a następnie drugi wiersz itd. Tablica Flags jest typu SKLatticeFlags, wyliczenie z następującymi elementami członkowskimi:

  • Default z wartością 0
  • Transparent z wartością 1

Jednak te flagi nie wydają się działać, ponieważ mają, i najlepiej je zignorować. Nie należy jednak ustawiać Flags właściwości na null. Ustaw ją na tablicę SKLatticeFlags wartości wystarczająco dużych, aby obejmowała całkowitą liczbę prostokątów.

Strona Lattice Nine Patch używa metody DrawBitmapLattice do naśladowania DrawBitmapNinePatch. Używa on tej samej mapy bitowej utworzonej w programie 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 Właściwości i YDivs są ustawione na tablice tylko dwóch liczb całkowitych, dzieląc mapę bitową na trzy paski zarówno poziomo, jak i pionowo: od piksela 0 do piksela 100 (renderowanego w rozmiarze pikseli), od pikseli 100 do pikseli 400 (rozciągnięty) i od pikseli 400 do pikseli 500 (rozmiar pikseli). XDivs Razem i YDivs zdefiniuj łącznie 9 prostokątów, czyli rozmiar tablicyFlags. Wystarczy utworzyć tablicę, aby utworzyć tablicę SKLatticeFlags.Default wartości.

Wyświetlacz jest identyczny z poprzednim programem:

Lattice Nine-Patch

Na stronie Ekran ściętego dzieli mapę bitową na 16 prostokątów:

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

Tablice XDivs i YDivs są nieco inne, co powoduje, że wyświetlanie nie jest tak symetryczne, jak w poprzednich przykładach:

Ekran trzęśniowy

W obrazach systemów iOS i Android po lewej stronie tylko mniejsze okręgi są renderowane w rozmiarach pikseli. Wszystko inne jest rozciągnięte.

Strona Wyświetlania lattice uogólnia tworzenie Flags tablicy, co pozwala na eksperymentowanie z XDivs i YDivs łatwiejsze. W szczególności warto zobaczyć, co się stanie po ustawieniu pierwszego elementu XDivs tablicy na YDivs wartość 0.