SkiaSharp bit eşlemlerinin bölümlenmiş görüntüsü

SkiaSharp SKCanvas nesnesi adlı DrawBitmapNinePatch bir yöntemi ve çok benzer olan adlı DrawBitmapLattice iki yöntemi tanımlar. Bu yöntemlerin her ikisi de bit eşlemi hedef dikdörtgenin boyutuna işler, ancak bit eşlemi tekdüzen olarak uzatmak yerine bit eşlem bölümlerini piksel boyutlarında görüntüler ve bit eşlemin diğer bölümlerini genişleterek dikdörtgene sığmasını sağlar:

Kesimli Örnekler

Bu yöntemler genellikle düğmeler gibi kullanıcı arabirimi nesnelerinin bir bölümünü oluşturan bit eşlemleri işlemek için kullanılır. Düğme tasarlarken, genellikle düğmenin boyutunun düğmenin içeriğine dayalı olmasını istersiniz, ancak büyük olasılıkla düğmenin içeriğinden bağımsız olarak düğme kenarlarının aynı genişlikte olmasını istersiniz. Bu, uygulamasının ideal bir uygulamasıdır DrawBitmapNinePatch.

DrawBitmapNinePatch özel bir durumdur DrawBitmapLattice , ancak iki yöntemin kullanılması ve anlaşılması daha kolaydır.

Dokuz yamalı ekran

Kavramsal olarak, DrawBitmapNinePatch bit eşlemi dokuz dikdörtgene böler:

Dokuz Yama

Dört köşedeki dikdörtgenler piksel boyutlarında görüntülenir. Okların gösterdiği gibi, bit eşlem kenarlarında yer alan diğer alanlar hedef dikdörtgenin alanına yatay veya dikey olarak uzatılır. Ortadaki dikdörtgen hem yatay hem de dikey olarak uzatılır.

Hedef dikdörtgende dört köşeyi bile piksel boyutlarında görüntülemek için yeterli alan yoksa, kullanılabilir boyuta kadar ölçeklendirilirler ve dört köşe dışında hiçbir şey görüntülenmez.

Bit eşlemi bu dokuz dikdörtgene bölmek için, yalnızca ortada dikdörtgenin belirtilmesi gerekir. Yönteminin söz dizimi DrawBitmapNinePatch budur:

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

Ortadaki dikdörtgen bit eşlem ile görelidir. Bu bir SKRectI değerdir (tamsayı sürümü SKRect) ve tüm koordinatlar ve boyutlar piksel cinsindendir. Hedef dikdörtgen, görüntü yüzeyine göredir. paint Bağımsız değişken isteğe bağlıdır.

Örnekteki Nine Patch Display sayfası ilk olarak türündeki SKBitmapbir genel statik özellik oluşturmak için statik bir oluşturucu kullanır:

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

Bu makaledeki diğer iki sayfada aynı bit eşlem kullanılır. Bit eşlem 500 piksel karedir ve her biri 100 piksel karelik bir alanı kaplayan, tümü aynı boyutta 25 daireden oluşan bir diziden oluşur:

Daire Kılavuzu

Programın örnek oluşturucu, bit eşlemi tüm ekran yüzeyine kadar uzatılmış olarak görüntülemek için kullanan DrawBitmapNinePatch bir PaintSurface işleyicisi oluştururSKCanvasView:

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

Dikdörtgen centerRect , 16 daireden oluşan merkezi diziyi kapsar. Köşelerdeki daireler piksel boyutlarında görüntülenir ve diğer her şey buna göre esnetilir:

Dokuz Yamalı Ekran

UWP sayfası 500 piksel genişliğindedir ve bu nedenle üst ve alt satırları aynı boyutta bir daire dizisi olarak görüntüler. Aksi takdirde, köşelerde olmayan tüm daireler üç nokta oluşturmak için esnetilir.

Dairelerin ve üç noktanın birleşiminden oluşan nesnelerin tuhaf bir görüntüsü için, dairelerin satırları ve sütunlarıyla çakışması için orta dikdörtgeni tanımlamayı deneyin:

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

Kafes ekranı

İki DrawBitmapLattice yöntem ile DrawBitmapNinePatchbenzerdir, ancak herhangi bir sayıda yatay veya dikey bölme için genelleştirilir. Bu bölmeler, piksellere karşılık gelen tamsayı dizileriyle tanımlanır.

DrawBitmapLattice Bu tamsayı dizileri için parametreleri olan yöntem çalışmıyor gibi görünüyor. DrawBitmapLattice türündeki SKLattice bir parametreye sahip yöntem çalışır ve aşağıda gösterilen örneklerde kullanılan yöntemdir.

Yapısı SKLattice dört özelliği tanımlar:

  • XDivs, bir tamsayı dizisi
  • YDivs, bir tamsayı dizisi
  • Flags, bir dizi SKLatticeFlags, bir numaralandırma türü
  • Boundsbit eşlem içinde isteğe bağlı bir kaynak dikdörtgen belirtmek için türünde Nullable<SKRectI>

Dizi bit XDivs eşlem genişliğini dikey şeritlere böler. İlk şerit, soldaki 0 pikselden öğesine XDivs[0]kadar uzanır. Bu şerit, piksel genişliğinde işlenir. İkinci şerit, 'den'e XDivs[0] XDivs[1]kadar uzanır ve esnetilir. Üçüncü şerit, 'den'e XDivs[1] XDivs[2] kadar uzanır ve piksel genişliğinde işlenir. Son şerit, dizinin son öğesinden bit eşlemin sağ kenarına kadar uzanır. Dizi çift sayıda öğeye sahipse, piksel genişliğinde görüntülenir. Aksi takdirde esnetilir. Toplam dikey şerit sayısı, dizideki öğelerin sayısından bir fazladır.

Dizi YDivs benzerdir. Dizinin yüksekliğini yatay şeritlere böler.

ve YDivs dizisi birlikte XDivs bit eşlemi dikdörtgenlere böler. Dikdörtgen sayısı, yatay şerit sayısı ve dikey şerit sayısı çarpımlarına eşittir.

Skia belgelerine göre, Flags dizi her dikdörtgen için bir öğe içerir, önce dikdörtgenlerin üst satırı, sonra ikinci satır vb. Dizi Flags türündedir SKLatticeFlagsve aşağıdaki üyelere sahip bir numaralandırmadır:

  • Default 0 değerine sahip
  • Transparent 1 değeriyle

Ancak, bu bayraklar gerektiği gibi çalışmıyor ve bunları yoksaymak en iyisidir. Ancak özelliğini olarak nullayarlamayınFlags. Bunu, toplam dikdörtgen sayısını kapsayacak kadar büyük bir değer dizisine SKLatticeFlags ayarlayın.

Lattice Nine Patch sayfası taklit DrawBitmapNinePatchetmek için kullanırDrawBitmapLattice. içinde oluşturulan NinePatchDisplayPagebit eşlemini kullanır:

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 Hem hem de YDivs özellikleri yalnızca iki tamsayıdan oluşan dizilere ayarlanır ve bit eşlemi hem yatay hem de dikey olarak üç şerite böler: piksel 0'dan piksel 100'e (piksel boyutunda işlenir), piksel 100'den piksel 400'e (esnetilmiş) ve piksel 400'den piksel 500'e (piksel boyutu). Birlikte ve XDivs YDivs dizinin boyutu Flags olan toplam 9 dikdörtgen tanımlayın. Yalnızca diziyi oluşturmak, bir değer dizisi SKLatticeFlags.Default oluşturmak için yeterlidir.

Görüntü, önceki programla aynıdır:

Kafes Dokuz Yamalı

Kafes Görüntüleme sayfası bit eşlemi 16 dikdörtgene böler:

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 ve YDivs dizileri biraz farklıdır ve bu da ekranın önceki örnekler kadar simetrik olmamasını sağlar:

Kafes Ekranı

Soldaki iOS ve Android görüntülerinde yalnızca piksel boyutlarında daha küçük daireler işlenir. Geri kalan her şey esnetildi.

Kafes Görüntüleme sayfası, dizinin oluşturulmasını Flags genelleştirerek ile XDivs YDivs ve daha kolay denemeler yapmanızı sağlar. Özellikle, veya YDivs dizisinin ilk öğesini XDivs 0 olarak ayarladığınızda ne olacağını görmek istersiniz.