Condividi tramite


Trasparenza skiaSharp

Come si è visto, la SKPaint classe include una Color proprietà di tipo SKColor. SKColor include un canale alfa, in modo che tutto ciò che si colora con un SKColor valore può essere parzialmente trasparente.

Alcune informazioni sulla trasparenza sono state illustrate nell'articolo Animazione di base in SkiaSharp . Questo articolo illustra in modo più approfondito la trasparenza per combinare più oggetti in una singola scena, una tecnica talvolta nota come fusione. Le tecniche di fusione più avanzate sono descritte negli articoli della sezione Shader SkiaSharp.

È possibile impostare il livello di trasparenza quando si crea un colore per la prima volta usando il costruttore a quattro parametri SKColor :

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

Un valore alfa pari a 0 è completamente trasparente e un valore alfa di 0xFF è completamente opaco. I valori tra questi due estremi creano colori parzialmente trasparenti.

Definisce inoltre SKColor un metodo pratico WithAlpha che crea un nuovo colore da un colore esistente, ma con il livello alfa specificato:

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

L'uso di testo parzialmente trasparente è illustrato nella tabella Codice più codice dell'esempio. Questa pagina dissolve due stringhe di testo all'interno e all'esterno incorporando la trasparenza nei SKColor valori:

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

Il transparency campo è animato per variare da 0 a 1 e di nuovo in un ritmo sinusoidale. La prima stringa di testo viene visualizzata con un valore alfa calcolato sottraendo il transparency valore da 1:

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

Il WithAlpha metodo imposta il componente alfa su un colore esistente, che qui è SKColors.Blue. La seconda stringa di testo usa un valore alfa calcolato dal transparency valore stesso:

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

L'animazione si alterna tra le due parole, invitando l'utente a "più codice" (o forse richiedendo "altro codice"):

Codice più codice

Nell'articolo precedente sulle nozioni di base di Bitmap in SkiaSharp è stato illustrato come visualizzare le bitmap usando uno dei DrawBitmap metodi di SKCanvas. Tutti i DrawBitmap metodi includono un SKPaint oggetto come ultimo parametro. Per impostazione predefinita, questo parametro è impostato su null ed è possibile ignorarlo.

In alternativa, è possibile impostare la Color proprietà di questo SKPaint oggetto per visualizzare una bitmap con un certo livello di trasparenza. L'impostazione Color di un livello di trasparenza nella proprietà di SKPaint consente di dissolvere le bitmap in entrata e in uscita o di dissolvere una bitmap in un'altra.

La trasparenza delle bitmap viene illustrata nella pagina Dissolvenza bitmap . Il file XAML crea un'istanza SKCanvasView di e :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>

Il file code-behind carica due risorse bitmap. Queste bitmap non sono le stesse dimensioni, ma sono le stesse proporzioni:

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

La Color proprietà dell'oggetto SKPaint è impostata su due livelli alfa complementari per le due bitmap. Quando si usano SKPaint con bitmap, non importa il resto del Color valore. Tutto ciò che conta è il canale alfa. Il codice qui chiama semplicemente il WithAlpha metodo sul valore predefinito della Color proprietà .

Lo spostamento delle Slider dissolvenza tra una bitmap e l'altra:

Dissolvenza bitmap

Negli ultimi articoli si è visto come usare SkiaSharp per disegnare testo, cerchi, ellissi, rettangoli arrotondati e bitmap. Il passaggio successivo è SkiaSharp Lines and Paths in cui si apprenderà come disegnare linee connesse in un percorso grafico.