Sdílet prostřednictvím


Průhlednost SkiaSharpu

Jak jste viděli, SKPaint třída obsahuje Color vlastnost typu SKColor. SKColor obsahuje alfa kanál, takže cokoli, co vybarvíte SKColor s hodnotou, může být částečně průhledné.

Některá průhlednost byla ukázaná v článku Základní animace ve SkiaSharpu. Tento článek se trochu hlouběji zabývá průhledností, aby zkombinuje více objektů v jedné scéně, což je technika, která se někdy označuje jako prolnutí. Pokročilejší techniky prolnutí jsou popsány v článcích v části shadery SkiaSharp.

Úroveň průhlednosti můžete nastavit při prvním vytvoření barvy pomocí konstruktoru se čtyřmi parametry SKColor :

SKColor (byte red, byte green, byte blue, byte alpha);

Alfa hodnota 0 je plně průhledná a alfa hodnota 0xFF je zcela neprůhledná. Hodnoty mezi těmito dvěma extrémními hodnotami vytvářejí barvy, které jsou částečně průhledné.

Kromě toho definuje praktickou WithAlpha metodu, SKColor která vytvoří novou barvu z existující barvy, ale se zadanou alfa úrovní:

SKColor halfTransparentBlue = SKColors.Blue.WithAlpha(0x80);

Použití částečně průhledného textu je znázorněno na stránce Code More Code v ukázce. Tato stránka zeslabí dva textové řetězce tím, že do SKColor hodnot začlení průhlednost:

public class CodeMoreCodePage : ContentPage
{
    SKCanvasView canvasView;
    bool isAnimating;
    Stopwatch stopwatch = new Stopwatch();
    double transparency;

    public CodeMoreCodePage ()
    {
        Title = "Code More Code";

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

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

        isAnimating = true;
        stopwatch.Start();
        Device.StartTimer(TimeSpan.FromMilliseconds(16), OnTimerTick);
    }

    protected override void OnDisappearing()
    {
        base.OnDisappearing();

        stopwatch.Stop();
        isAnimating = false;
    }

    bool OnTimerTick()
    {
        const int duration = 5;     // seconds
        double progress = stopwatch.Elapsed.TotalSeconds % duration / duration;
        transparency = 0.5 * (1 + Math.Sin(progress * 2 * Math.PI));
        canvasView.InvalidateSurface();

        return isAnimating;
    }

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

        canvas.Clear();

        const string TEXT1 = "CODE";
        const string TEXT2 = "MORE";

        using (SKPaint paint = new SKPaint())
        {
            // Set text width to fit in width of canvas
            paint.TextSize = 100;
            float textWidth = paint.MeasureText(TEXT1);
            paint.TextSize *= 0.9f * info.Width / textWidth;

            // Center first text string
            SKRect textBounds = new SKRect();
            paint.MeasureText(TEXT1, ref textBounds);

            float xText = info.Width / 2 - textBounds.MidX;
            float yText = info.Height / 2 - textBounds.MidY;

            paint.Color = SKColors.Blue.WithAlpha((byte)(0xFF * (1 - transparency)));
            canvas.DrawText(TEXT1, xText, yText, paint);

            // Center second text string
            textBounds = new SKRect();
            paint.MeasureText(TEXT2, ref textBounds);

            xText = info.Width / 2 - textBounds.MidX;
            yText = info.Height / 2 - textBounds.MidY;

            paint.Color = SKColors.Blue.WithAlpha((byte)(0xFF * transparency));
            canvas.DrawText(TEXT2, xText, yText, paint);
        }
    }
}

Pole transparency je animované, aby se liší od 0 do 1 a zpět v sinusoidní rytmus. První textový řetězec se zobrazí s alfa hodnotou vypočítanou odečtením transparency hodnoty od 1:

paint.Color = SKColors.Blue.WithAlpha((byte)(0xFF * (1 - transparency)));

Metoda WithAlpha nastaví alfa komponentu na existující barvu, která zde je SKColors.Blue. Druhý textový řetězec používá alfa hodnotu vypočítanou ze transparency samotné hodnoty:

paint.Color = SKColors.Blue.WithAlpha((byte)(0xFF * transparency));

Animace se mezi těmito dvěma slovy střídá tím, že uživatele požádá o "kód více" (nebo třeba požádá o "více kódu"):

Code More Code

V předchozím článku o Bitmap Základy v SkiaSharp, jste viděli, jak zobrazit rastrové obrázky pomocí jedné z DrawBitmap metod SKCanvas. DrawBitmap Všechny metody zahrnují SKPaint objekt jako poslední parametr. Ve výchozím nastavení je tento parametr nastavený null a můžete ho ignorovat.

Alternativně můžete nastavit vlastnost tohoto SKPaint objektu Color pro zobrazení rastrového obrázku s určitou úrovní průhlednosti. Nastavení úrovně průhlednosti ve Color vlastnosti SKPaint umožňuje vyblednout rastrové obrázky dovnitř a ven, nebo rozpustit jeden rastrový obrázek do jiné.

Průhlednost rastrového obrázku je znázorněna na stránce Rozpustit rastr. Soubor XAML vytvoří SKCanvasView instanci a Slider:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:skia="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms"
             x:Class="SkiaSharpFormsDemos.Effects.BitmapDissolvePage"
             Title="Bitmap Dissolve">
    <StackLayout>
        <skia:SKCanvasView x:Name="canvasView"
                           VerticalOptions="FillAndExpand"
                           PaintSurface="OnCanvasViewPaintSurface" />

        <Slider x:Name="progressSlider"
                Margin="10"
                ValueChanged="OnSliderValueChanged" />
    </StackLayout>
</ContentPage>

Soubor kódu za kódem načte dva rastrové zdroje. Tyto rastrové obrázky nemají stejnou velikost, ale mají stejný poměr stran:

public partial class BitmapDissolvePage : ContentPage
{
    SKBitmap bitmap1;
    SKBitmap bitmap2;

    public BitmapDissolvePage()
    {
        InitializeComponent();

        // Load two bitmaps
        Assembly assembly = GetType().GetTypeInfo().Assembly;

        using (Stream stream = assembly.GetManifestResourceStream(
                                "SkiaSharpFormsDemos.Media.SeatedMonkey.jpg"))
        {
            bitmap1 = SKBitmap.Decode(stream);
        }
        using (Stream stream = assembly.GetManifestResourceStream(
                                "SkiaSharpFormsDemos.Media.FacePalm.jpg"))
        {
            bitmap2 = SKBitmap.Decode(stream);
        }
    }

    void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
    {
        canvasView.InvalidateSurface();
    }

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

        canvas.Clear();

        // Find rectangle to fit bitmap
        float scale = Math.Min((float)info.Width / bitmap1.Width,
                                (float)info.Height / bitmap1.Height);
        SKRect rect = SKRect.Create(scale * bitmap1.Width,
                                    scale * bitmap1.Height);
        float x = (info.Width - rect.Width) / 2;
        float y = (info.Height - rect.Height) / 2;
        rect.Offset(x, y);

        // Get progress value from Slider
        float progress = (float)progressSlider.Value;

        // Display two bitmaps with transparency
        using (SKPaint paint = new SKPaint())
        {
            paint.Color = paint.Color.WithAlpha((byte)(0xFF * (1 - progress)));
            canvas.DrawBitmap(bitmap1, rect, paint);

            paint.Color = paint.Color.WithAlpha((byte)(0xFF * progress));
            canvas.DrawBitmap(bitmap2, rect, paint);
        }
    }
}

Vlastnost Color objektu SKPaint je nastavena na dvě doplňkové alfa úrovně pro dvě rastrové obrázky. Při použití SKPaint s rastrovými obrázky nezáleží na tom, co je zbytek Color hodnoty. Vše, co je důležité, je alfa kanál. Kód zde jednoduše volá metodu WithAlpha na výchozí hodnotu Color vlastnosti.

Slider Přesouvání rozpouští mezi jedním rastrem a druhým:

Rastrový obrázek rozpustit

V předchozích několika článcích jste viděli, jak pomocí SkiaSharp nakreslit text, kruhy, tři tečky, zaoblené obdélníky a rastrové obrázky. Dalším krokem jsou čáry a cesty SkiaSharp, ve kterém se dozvíte, jak nakreslit propojené čáry v grafické cestě.