Ayrıştırılamayan karışım modları

SkiaSharp ayrıştırılabilir karışım modları makalesinde gördüğünüz gibi, ayrıştırılabilir karışım modları kırmızı, yeşil ve mavi kanallarda ayrı ayrı işlemler gerçekleştirir. Ayrıştırılamayan karışım modları değildir. Renk Tonu, Doygunluk ve Parlaklık düzeyleri üzerinde çalışarak, ayrıştırılamayan karışım modları renkleri ilginç şekillerde değiştirebilir:

Ayrıştırılamayan Örnek

Ton-Doygunluk-Parlaklık modeli

Ayrıştırılamayan karışım modlarını anlamak için hedef ve kaynak pikselleri Hue-Saturation-Luminosity modelinde renkler olarak ele almak gerekir. (Parlaklık, Hafiflik olarak da adlandırılır.)

HSL renk modeli ileXamarin.Forms tümleştirme makalesinde ele alınmıştı ve bu makaledeki örnek bir program HSL renkleri ile denemelere izin veriyor. Statik SKColor.FromHsl yöntemle Ton, Doygunluk ve Parlaklık değerlerini kullanarak bir SKColor değer oluşturabilirsiniz.

Hue, rengin baskın dalga boyunu temsil eder. Ton değerleri 0 ile 360 arasında değişir ve katkısal ve subtraktif öncelikler arasında döngü oluşturur: Kırmızı değer 0, sarı 60, yeşil 120, camgöbeği 180, mavi 240, eflatun 300 ve döngü 360'ta kırmızıya döner.

Baskın bir renk yoksa (örneğin, renk beyaz veya siyah ya da gri bir tondur) Ton tanımlanmamıştır ve genellikle 0 olarak ayarlanır.

Doygunluk değerleri 0 ile 100 arasında değişebilir ve rengin saflığını gösterebilir. 100 doygunluk değeri en saf renktir, 100'den düşük değerler ise rengin daha gri olmasına neden olur. 0 doygunluk değeri gri tonunda sonuç verir.

Luminosity (veya Lightness) değeri rengin ne kadar parlak olduğunu gösterir. 0 parlaklık değeri, diğer ayarlardan bağımsız olarak siyahtır. Benzer şekilde, 100 parlaklık değeri beyazdır.

HSL değeri (0, 100, 50), saf kırmızı olan RGB değeridir (FF, 00, 00). HSL değeri (180, 100, 50) RGB değeridir (00, FF, FF), saf camdır. Doygunluk azaldıkça baskın renk bileşeni azalır ve diğer bileşenler artar. Doygunluk düzeyi 0 olduğunda, tüm bileşenler aynı ve renk gri bir tondur. Siyaha gitmek için Luminosity'yi azaltın; Beyaza gitmek için Luminosity'yi artırın.

Karışım modları ayrıntılı olarak

Diğer harmanlama modlarında olduğu gibi, ayrıştırılamayan dört karışım modu da bir hedef (genellikle bit eşlem görüntüsüdür) ve genellikle tek bir renk veya gradyan olan bir kaynak içerir. Harmanlama modları hedeften ve kaynaktan Gelen Hue, Doygunluk ve Luminosity değerlerini birleştirir:

Blend Modu Kaynaktan bileşenler Hedeften bileşenler
Hue Ton Doygunluk ve Parlaklık
Saturation Doygun -luk Ton ve Parlaklık
Color Ton ve Doygunluk Parlak -lık
Luminosity Parlak -lık Ton ve Doygunluk

Algoritmalar için W3C Birleştirme ve Harmanlama Düzeyi 1 belirtimine bakın.

Ayrıştırılamayan Blend Modları sayfası, bu karışım modlarından birini seçmek için bir Picker ve HSL rengi seçmek için üç Slider görünüm içerir:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:skia="clr-namespace:SkiaSharp;assembly=SkiaSharp"
             xmlns:skiaviews="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms"
             x:Class="SkiaSharpFormsDemos.Effects.NonSeparableBlendModesPage"
             Title="Non-Separable Blend Modes">

    <StackLayout>
        <skiaviews:SKCanvasView x:Name="canvasView"
                                VerticalOptions="FillAndExpand"
                                PaintSurface="OnCanvasViewPaintSurface" />

        <Picker x:Name="blendModePicker"
                Title="Blend Mode"
                Margin="10, 0"
                SelectedIndexChanged="OnPickerSelectedIndexChanged">
            <Picker.ItemsSource>
                <x:Array Type="{x:Type skia:SKBlendMode}">
                    <x:Static Member="skia:SKBlendMode.Hue" />
                    <x:Static Member="skia:SKBlendMode.Saturation" />
                    <x:Static Member="skia:SKBlendMode.Color" />
                    <x:Static Member="skia:SKBlendMode.Luminosity" />
                </x:Array>
            </Picker.ItemsSource>

            <Picker.SelectedIndex>
                0
            </Picker.SelectedIndex>
        </Picker>

        <Slider x:Name="hueSlider"
                Maximum="360"
                Margin="10, 0"
                ValueChanged="OnSliderValueChanged" />

        <Slider x:Name="satSlider"
                Maximum="100"
                Margin="10, 0"
                ValueChanged="OnSliderValueChanged" />

        <Slider x:Name="lumSlider"
                Maximum="100"
                Margin="10, 0"
                ValueChanged="OnSliderValueChanged" />

        <StackLayout Orientation="Horizontal">
            <Label x:Name="hslLabel"
                   HorizontalOptions="CenterAndExpand" />

            <Label x:Name="rgbLabel"
                   HorizontalOptions="CenterAndExpand" />

        </StackLayout>
    </StackLayout>
</ContentPage>

Alandan tasarruf etmek için, üç Slider görünüm programın kullanıcı arabiriminde tanımlanmaz. Sıranın Ton, Doygunluk ve Parlaklık olduğunu unutmamanız gerekir. Sayfanın alt kısmındaki iki Label görünümde HSL ve RGB renk değerleri gösterilir.

Arka planda kod dosyası bit eşlem kaynaklarından birini yükler, bunu tuvalde mümkün olduğunca büyük görüntüler ve ardından tuvali bir dikdörtgenle kaplar. Dikdörtgen rengi üç Slider görünümü temel alır ve karıştırma modu içinde Pickerseçilen görünümdür:

public partial class NonSeparableBlendModesPage : ContentPage
{
    SKBitmap bitmap = BitmapExtensions.LoadBitmapResource(
                        typeof(NonSeparableBlendModesPage),
                        "SkiaSharpFormsDemos.Media.Banana.jpg");
    SKColor color;

    public NonSeparableBlendModesPage()
    {
        InitializeComponent();
    }

    void OnPickerSelectedIndexChanged(object sender, EventArgs args)
    {
        canvasView.InvalidateSurface();
    }

    void OnSliderValueChanged(object sender, ValueChangedEventArgs e)
    {
        // Calculate new color based on sliders
        color = SKColor.FromHsl((float)hueSlider.Value,
                                (float)satSlider.Value,
                                (float)lumSlider.Value);

        // Use labels to display HSL and RGB color values
        color.ToHsl(out float hue, out float sat, out float lum);

        hslLabel.Text = String.Format("HSL = {0:F0} {1:F0} {2:F0}",
                                      hue, sat, lum);

        rgbLabel.Text = String.Format("RGB = {0:X2} {1:X2} {2:X2}",
                                      color.Red, color.Green, color.Blue);

        canvasView.InvalidateSurface();
    }

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

        canvas.Clear();
        canvas.DrawBitmap(bitmap, info.Rect, BitmapStretch.Uniform);

        // Get blend mode from Picker
        SKBlendMode blendMode =
            (SKBlendMode)(blendModePicker.SelectedIndex == -1 ?
                                        0 : blendModePicker.SelectedItem);

        using (SKPaint paint = new SKPaint())
        {
            paint.Color = color;
            paint.BlendMode = blendMode;
            canvas.DrawRect(info.Rect, paint);
        }
    }
}

Programın üç kaydırıcı tarafından seçilen HSL renk değerini görüntülemediğini fark edin. Bunun yerine, bu kaydırıcılardan bir renk değeri oluşturur ve ton ToHsl , Doygunluk ve Parlaklık değerlerini elde etmek için yöntemini kullanır. Bunun nedeni, yöntemin FromHsl bir HSL rengini, dahili olarak yapıda depolanan RGB rengine dönüştürmesidir SKColor . ToHsl Yöntemi RGB'den HSL'ye dönüştürür, ancak sonuç her zaman özgün değer olmaz.

Örneğin, FromHsl HSL değerini (180, 50, 0) RGB rengine (0, 0, 0) dönüştürür çünkü Luminosity sıfırdır. Ton ToHsl ve Doygunluk değerleri ilgisiz olduğundan yöntemi RGB rengini (0, 0, 0) HSL rengine (0, 0, 0) dönüştürür. Bu programı kullanırken, kaydırıcılarla belirttiğiniz renk yerine programın kullandığı HSL renginin gösterimini görmeniz daha iyidir.

Karıştırma SKBlendModes.Hue modu, hedefin Doygunluk ve Parlaklık düzeylerini korurken kaynağın Hue düzeyini kullanır. Bu karıştırma modunu test ettiğinizde, doygunluk ve parlaklık kaydırıcıları 0 veya 100 dışında bir değere ayarlanmalıdır çünkü bu durumlarda Hue benzersiz olarak tanımlanmamıştır.

Ayrıştırılamayan Blend Modları - Ton

Kaydırıcıyı 0 olarak ayarladığınızda (soldaki iOS ekran görüntüsünde olduğu gibi), her şey kırmızımsı olur. Ancak bu, görüntünün tamamen yeşil ve mavi olmadığı anlamına gelmez. Açıkçası sonuçta hala gri tonlar var. Örneğin RGB rengi (40, 40, C0) HSL rengine (240, 50, 50) eşdeğerdir. Ton mavidir, ancak 50 doygunluk değeri de kırmızı ve yeşil bileşenler olduğunu gösterir. Hue ile 0 SKBlendModes.Hueolarak ayarlanırsa, HSL rengi RGB rengi (C0, 40, 40) olan (0, 50, 50) olur. Hala mavi ve yeşil bileşenler vardır, ancak baskın bileşen artık kırmızıdır.

Karışım SKBlendModes.Saturation modu, kaynağın Doygunluk düzeyini hedefin Ton ve Parlaklık düzeyiyle birleştirir. Renk Tonu gibi, Parlaklık 0 veya 100 ise Doygunluk iyi tanımlanmaz. Teoride, bu iki uç değer arasındaki herhangi bir Parlaklık ayarı işe yaramalıdır. Ancak Luminosity ayarı sonucu olması gerekenden daha fazla etkiliyor gibi görünüyor. Parlaklığı 50 olarak ayarladığınızda resmin Doygunluk düzeyini nasıl ayarlayabileceğinizi görebilirsiniz:

Ayrıştırılamayan Blend Modları - Doygunluk

Donuk bir görüntünün renk Doygunluğunu artırmak için bu karıştırma modunu kullanabilir veya yalnızca gri tonlardan oluşan bir sonuç görüntüsü için Doygunluğu sıfıra düşürebilirsiniz (soldaki iOS ekran görüntüsünde olduğu gibi).

Karışım SKBlendModes.Color modu hedefin Parlaklığını korur ancak kaynağın Ton ve Doygunluk değerlerini kullanır. Bu da aşırı uçlar arasında herhangi bir yerde luminosity kaydırıcısının herhangi bir ayarının çalışması gerektiğini gösterir.

Ayrıştırılamayan Blend Modları - Renk

Kısa süre sonra bu karışım modunun bir uygulamasını göreceksiniz.

Son olarak, SKBlendModes.Luminosity karıştırma modu tam tersidir SKBlendModes.Color. Hedefin Ton ve Doygunluğunu korur, ancak kaynağın Parlaklığını kullanır. Karışım Luminosity modu toplu işlerden en gizemlisi: Ton ve Doygunluk kaydırıcıları görüntüyü etkiler, ancak orta parlaklıkta bile görüntü ayrı değildir:

Ayrıştırılamayan Blend Modları - Parlaklık

Teoride, bir görüntünün Parlaklığını artırmak veya azaltmak onu daha açık veya koyu hale getirmelidir. Bu Luminosity özellik örneği veya bu SKBlendMode Enum tanımlaması ilgi çekici olabilir.

Genellikle, hedef görüntünün tamamına uygulanan tek bir renkten oluşan bir kaynakla ayrıştırılamayan karıştırma modlarından birini kullanmak istemezsiniz. Etkisi çok büyük. Efekti görüntünün bir bölümüyle kısıtlamak istersiniz. Bu durumda, kaynak büyük olasılıkla transparansiyi birleştirir veya belki de kaynak daha küçük bir grafikle sınırlandırılır.

Ayrıştırılabilir mod için mat

Örnekte kaynak olarak dahil edilen bit eşlemlerden biri aşağıda verilmiştir. Dosya adı Banana.jpg:

Muz Maymunu

Sadece muzu kapsayan bir mat oluşturmak mümkündür. Bu aynı zamanda örnekteki bir kaynaktır. Dosya adı BananaMatte.png:

Muz Mat

Siyah muz şeklinin yanı sıra bit eşleminin geri kalanı saydamdır.

Mavi Muz sayfası, maymunun tuttuğu muzun Hue ve Doygunluğunu değiştirmek için bu mat rengi kullanır, ancak görüntüdeki başka hiçbir şeyi değiştirmez.

Aşağıdaki BlueBananaPage sınıfta, Banana.jpg bit eşlem bir alan olarak yüklenir. Oluşturucu, nesne olarak BananaMatte.png bit eşlemini matteBitmap yükler, ancak bu nesneyi oluşturucunun dışında tutmaz. Bunun yerine, adlı blueBananaBitmap üçüncü bir bit eşlem oluşturulur. üzerine matteBitmap çizilir ve ardından mavi ve BlendMode ayarı olarak ayarlanmış SKBlendMode.SrcInbir SKPaint Color olurblueBananaBitmap. Çoğunlukla blueBananaBitmap saydam kalır, ancak muz düz saf mavi bir görüntü ile:

public class BlueBananaPage : ContentPage
{
    SKBitmap bitmap = BitmapExtensions.LoadBitmapResource(
        typeof(BlueBananaPage),
        "SkiaSharpFormsDemos.Media.Banana.jpg");

    SKBitmap blueBananaBitmap;

    public BlueBananaPage()
    {
        Title = "Blue Banana";

        // Load banana matte bitmap (black on transparent)
        SKBitmap matteBitmap = BitmapExtensions.LoadBitmapResource(
            typeof(BlueBananaPage),
            "SkiaSharpFormsDemos.Media.BananaMatte.png");

        // Create a bitmap with a solid blue banana and transparent otherwise
        blueBananaBitmap = new SKBitmap(matteBitmap.Width, matteBitmap.Height);

        using (SKCanvas canvas = new SKCanvas(blueBananaBitmap))
        {
            canvas.Clear();
            canvas.DrawBitmap(matteBitmap, new SKPoint(0, 0));

            using (SKPaint paint = new SKPaint())
            {
                paint.Color = SKColors.Blue;
                paint.BlendMode = SKBlendMode.SrcIn;
                canvas.DrawPaint(paint);
            }
        }

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

        canvas.DrawBitmap(bitmap, info.Rect, BitmapStretch.Uniform);

        using (SKPaint paint = new SKPaint())
        {
            paint.BlendMode = SKBlendMode.Color;
            canvas.DrawBitmap(blueBananaBitmap,
                              info.Rect,
                              BitmapStretch.Uniform,
                              paint: paint);
        }
    }
}

İşleyici PaintSurface bit eşlemi muz tutan maymunla çizer. Bu kodun ardından ile SKBlendMode.Colorgörüntüsü gösterilirblueBananaBitmap. Muzun yüzeyinde her pikselin Tonu ve Doygunluğu, 240 ton değerine ve 100 doygunluk değerine karşılık gelen düz mavi ile değiştirilir. Ancak Parlaklık aynı kalır, yani muz yeni rengine rağmen gerçekçi bir dokuya sahip olmaya devam eder:

Mavi Muz

Karıştırma modunu olarak SKBlendMode.Saturationdeğiştirmeyi deneyin. Muz sarı kalır ama daha yoğun sarıdır. Gerçek hayattaki bir uygulamada bu, muzu maviye döndürmekten daha cazip bir etki olabilir.