SkiaSharp'ta Bit Eşlem Temelleri

Çeşitli kaynaklardan bit eşlemleri yükleyin ve görüntüleyin.

SkiaSharp'ta bit eşlemlerin desteği oldukça kapsamlıdır. Bu makalede yalnızca bit eşlemlerin nasıl yükleneceği ve bunların nasıl görüntüleneceğiyle ilgili temel bilgiler yer alır:

İki bit eşlem görüntüsü

Bit eşlemlerin çok daha derin bir keşfi SkiaSharp Bit Eşlemleri bölümünde bulunabilir.

SkiaSharp bit eşlemi türünde SKBitmapbir nesnedir. Bit eşlem oluşturmanın birçok yolu vardır, ancak bu makale kendisini SKBitmap.Decode bir .NET Stream nesnesinden bit eşlem yükleyen yöntemiyle kısıtlar.

SkiaSharpFormsDemos programının Temel Bit Eşlemler sayfasında üç farklı kaynaktan bit eşlemlerin nasıl yüklenecekleri gösterilmektedir:

  • İnternet üzerinden
  • Yürütülebilir dosyaya eklenmiş bir kaynaktan
  • Kullanıcının fotoğraf kitaplığından

Bu üç kaynak için üç SKBitmap nesne sınıfında alan BasicBitmapsPage olarak tanımlanır:

public class BasicBitmapsPage : ContentPage
{
    SKCanvasView canvasView;
    SKBitmap webBitmap;
    SKBitmap resourceBitmap;
    SKBitmap libraryBitmap;

    public BasicBitmapsPage()
    {
        Title = "Basic Bitmaps";

        canvasView = new SKCanvasView();
        canvasView.PaintSurface += OnCanvasViewPaintSurface;
        Content = canvasView;
        ...
    }
    ...
}

Web'den Bit Eşlem Yükleme

URL'yi temel alan bir bit eşlem yüklemek için sınıfını HttpClient kullanabilirsiniz. Yalnızca bir örneğini HttpClient oluşturup yeniden kullanmanız gerekir, bu nedenle alanı olarak depolayın:

HttpClient httpClient = new HttpClient();

iOS ve Android uygulamalarıyla kullanırkenHttpClient, Aktarım Katmanı Güvenliği (TLS) 1.2 belgelerinde açıklandığı gibi proje özelliklerini ayarlamak istersiniz.

işlecini await ile HttpClientkullanmak en uygun olduğu için kod oluşturucuda BasicBitmapsPage yürütülemez. Bunun yerine, geçersiz kılmanın OnAppearing bir parçasıdır. Buradaki URL, Xamarin web sitesindeki bazı örnek bit eşlemleri içeren bir alanı gösterir. Web sitesindeki bir paket, bit eşlemi belirli bir genişliğe yeniden boyutlandırmak için belirtim eklemeye olanak tanır:

protected override async void OnAppearing()
{
    base.OnAppearing();

    // Load web bitmap.
    string url = "https://developer.xamarin.com/demo/IMG_3256.JPG?width=480";

    try
    {
        using (Stream stream = await httpClient.GetStreamAsync(url))
        using (MemoryStream memStream = new MemoryStream())
        {
            await stream.CopyToAsync(memStream);
            memStream.Seek(0, SeekOrigin.Begin);

            webBitmap = SKBitmap.Decode(memStream);
            canvasView.InvalidateSurface();
        };
    }
    catch
    {
    }
}

Bir ana iş parçacığında uzun bir işlem gerçekleştirdiğinden, Android işletim sistemi yönteminde SKBitmap.Decode döndürülen GetStreamAsync öğesini kullanırken Stream bir özel durum oluşturur. Bu nedenle, bit eşlem dosyasının içeriği kullanılarak CopyToAsyncbir MemoryStream nesneye kopyalanır.

Bit eşlem dosyalarının kodunu çözmek statik SKBitmap.Decode yöntemden sorumludur. JPEG, PNG ve GIF bit eşlem biçimleriyle çalışır ve sonuçları iç SkiaSharp biçiminde depolar. Bu noktada, işleyicinin SKCanvasView görüntüyü güncelleştirmesine izin vermek PaintSurface için geçersiz kılınması gerekir.

Bit Eşlem Kaynağı Yükleme

Kod açısından, bit eşlemleri yüklemenin en kolay yaklaşımı, doğrudan uygulamanıza bir bit eşlem kaynağı eklemektir. SkiaSharpFormsDemos programı, monkey.png adlı bir dosya da dahil olmak üzere çeşitli bit eşlem dosyalarını içeren Media adlı bir klasör içerir. Program kaynakları olarak depolanan bit eşlemler için, Özellikler iletişim kutusunu kullanarak dosyaya Ekli Kaynağın Derleme Eyleminivermelisiniz!

Katıştırılmış her kaynağın proje adı, klasör ve dosya adından oluşan bir kaynak kimliği vardır ve bunların tümü noktalarla bağlanır: SkiaSharpFormsDemos.Media.monkey.png. Bu kaynak kimliğini sınıfın yöntemine Assembly bağımsız değişken GetManifestResourceStream olarak belirterek bu kaynağa erişebilirsiniz:

string resourceID = "SkiaSharpFormsDemos.Media.monkey.png";
Assembly assembly = GetType().GetTypeInfo().Assembly;

using (Stream stream = assembly.GetManifestResourceStream(resourceID))
{
    resourceBitmap = SKBitmap.Decode(stream);
}

Bu Stream nesne doğrudan yöntemine SKBitmap.Decode geçirilebilir.

Fotoğraf Kitaplığından Bit Eşlem Yükleme

Kullanıcının cihazın resim kitaplığından fotoğraf yüklemesi de mümkündür. Bu tesis kendi kendine Xamarin.Forms sağlanmaz. İş, Resim Kitaplığı'ndan Fotoğraf Seçme makalesinde açıklanan gibi bir bağımlılık hizmeti gerektirir.

SkiaSharpFormsDemos projesindeki IPhotoLibrary.cs dosyası ve platform projelerindeki üç PhotoLibrary.cs dosyası bu makaleden uyarlanmıştır. Buna ek olarak, Android MainActivity.cs dosyası makalede açıklandığı gibi değiştirilmiştir ve iOS projesine info.plist dosyasının en altına doğru iki satırla fotoğraf kitaplığına erişme izni verilmiştir.

Oluşturucu, BasicBitmapsPage dokunmaların bildirilmesi için öğesine bir TapGestureRecognizerSKCanvasView ekler. Bir dokunmanın alınmasıyla Tapped işleyici, resim seçici bağımlılık hizmetine erişir ve öğesini çağırır PickPhotoAsync. Bir Stream nesne döndürülürse yöntemine SKBitmap.Decode geçirilir:

// Add tap gesture recognizer
TapGestureRecognizer tapRecognizer = new TapGestureRecognizer();
tapRecognizer.Tapped += async (sender, args) =>
{
    // Load bitmap from photo library
    IPhotoLibrary photoLibrary = DependencyService.Get<IPhotoLibrary>();

    using (Stream stream = await photoLibrary.PickPhotoAsync())
    {
        if (stream != null)
        {
            libraryBitmap = SKBitmap.Decode(stream);
            canvasView.InvalidateSurface();
        }
    }
};
canvasView.GestureRecognizers.Add(tapRecognizer);

İşleyicinin nesnesinin TappedInvalidateSurface yöntemini de çağırdığını SKCanvasView görebilirsiniz. Bu, işleyiciye PaintSurface yeni bir çağrı oluşturur.

Bit Eşlemleri Görüntüleme

İşleyicinin PaintSurface üç bit eşlem görüntülemesi gerekir. İşleyici, telefonun dikey modda olduğunu varsayar ve tuvali dikey olarak üç eşit parçaya böler.

İlk bit eşlem en DrawBitmap basit yöntemle görüntülenir. Tek belirtmeniz gereken bit eşleminin sol üst köşesinin konumlandırılacağı X ve Y koordinatlarıdır:

public void DrawBitmap (SKBitmap bitmap, Single x, Single y, SKPaint paint = null)

Bir SKPaint parametre tanımlanmış olsa da, parametresinin null varsayılan değeri vardır ve bunu yoksayabilirsiniz. Bit eşlem pikselleri, bire bir eşleme ile görüntü yüzeyinin piksellerine aktarılır. SkiaSharp Saydamlığı'nın sonraki bölümünde bu SKPaint bağımsız değişken için bir uygulama göreceksiniz.

Bir program ve Height özellikleriyle bit eşlem Width piksel boyutlarını elde edebilir. Bu özellikler, programın bit eşlemi tuvalin üçüncü üst kısmının ortasına konumlandırmak için koordinatları hesaplamasına olanak sağlar:

void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
    SKImageInfo info = args.Info;
    SKSurface surface = args.Surface;
    SKCanvas canvas = surface.Canvas;

    canvas.Clear();

    if (webBitmap != null)
    {
        float x = (info.Width - webBitmap.Width) / 2;
        float y = (info.Height / 3 - webBitmap.Height) / 2;
        canvas.DrawBitmap(webBitmap, x, y);
    }
    ...
}

Diğer iki bit eşlem, parametresi olan bir sürümüyle DrawBitmapSKRect görüntülenir:

public void DrawBitmap (SKBitmap bitmap, SKRect dest, SKPaint paint = null)

Üçüncü bir sürümü, DrawBitmap görüntülenecek bit eşlem dikdörtgen alt kümesini belirtmek için iki SKRect bağımsız değişkene sahiptir, ancak bu sürüm bu makalede kullanılmaz.

Ekli bir kaynak bit eşleminden yüklenen bit eşlemi görüntülemek için kod aşağıdadır:

void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
    ...
    if (resourceBitmap != null)
    {
        canvas.DrawBitmap(resourceBitmap,
            new SKRect(0, info.Height / 3, info.Width, 2 * info.Height / 3));
    }
    ...
}

Bit eşlem dikdörtgenin boyutlarına kadar uzatılır, bu nedenle maymun şu ekran görüntülerinde yatay olarak esnetilir:

Temel Bit Eşlemler sayfasının üç kez ekran görüntüsü

Üçüncü görüntü (yalnızca programı çalıştırdığınızda ve kendi resim kitaplığınızdan bir fotoğraf yüklediğinizde görebilirsiniz) dikdörtgen içinde de görüntülenir, ancak bit eşlemin en boy oranını korumak için dikdörtgenin konumu ve boyutu ayarlanır. Bit eşlem ve hedef dikdörtgenin boyutuna göre bir ölçeklendirme faktörünün hesaplanması ve dikdörtgenin bu alanda ortalanması gerektiğinden bu hesaplama biraz daha fazla söz konusudur:

void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
    ...
    if (libraryBitmap != null)
    {
        float scale = Math.Min((float)info.Width / libraryBitmap.Width,
                               info.Height / 3f / libraryBitmap.Height);

        float left = (info.Width - scale * libraryBitmap.Width) / 2;
        float top = (info.Height / 3 - scale * libraryBitmap.Height) / 2;
        float right = left + scale * libraryBitmap.Width;
        float bottom = top + scale * libraryBitmap.Height;
        SKRect rect = new SKRect(left, top, right, bottom);
        rect.Offset(0, 2 * info.Height / 3);

        canvas.DrawBitmap(libraryBitmap, rect);
    }
    else
    {
        using (SKPaint paint = new SKPaint())
        {
            paint.Color = SKColors.Blue;
            paint.TextAlign = SKTextAlign.Center;
            paint.TextSize = 48;

            canvas.DrawText("Tap to load bitmap",
                info.Width / 2, 5 * info.Height / 6, paint);
        }
    }
}

Resim kitaplığından henüz bir bit eşlem yüklenmemişse, else blokta kullanıcıdan ekrana dokunmasını isteyen bir metin görüntülenir.

Çeşitli saydamlık dereceleriyle bit eşlemleri görüntüleyebilirsiniz ve SkiaSharp Saydamlığı'nın sonraki makalesinde bunun nasıl olduğu açıklanmaktadır.