Freigeben über


SkiaSharp Transparenz

Wie Sie gesehen haben, enthält die SKPaint Klasse eine Color Eigenschaft vom Typ SKColor. SKColor enthält einen Alphakanal, sodass alles, was Sie mit einem SKColor Wert einfärben, teilweise transparent sein kann.

Einige Transparenz wurde im Artikel "Basic Animation in SkiaSharp " veranschaulicht. Dieser Artikel geht etwas tiefer in die Transparenz, um mehrere Objekte in einer einzelnen Szene zu kombinieren, eine Technik, die manchmal als Vermischung bezeichnet wird. Komplexere Mischtechniken werden in den Artikeln im Abschnitt SkiaSharp-Shader erläutert.

Sie können die Transparenzstufe festlegen, wenn Sie zuerst eine Farbe mit dem Konstruktor mit vier Parametern SKColor erstellen:

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

Ein Alphawert von 0 ist vollständig transparent und ein Alphawert von 0xFF ist vollständig undurchsichtig. Werte zwischen diesen beiden Extremen erzeugen Farben, die teilweise transparent sind.

Definiert außerdem eine praktische WithAlpha Methode, die eine neue Farbe aus einer vorhandenen Farbe erstellt, SKColor aber mit der angegebenen Alphaebene:

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

Die Verwendung teilweise transparenter Texte wird auf der Code More Code-Seite im Beispiel veranschaulicht. Auf dieser Seite werden zwei Textzeichenfolgen eingeblendet und ausgeblendet, indem Transparenz in die SKColor Werte einbezogen wird:

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

Das transparency Feld ist animiert, von 0 bis 1 und wieder in einem sinusoidalen Rhythmus zu variieren. Die erste Textzeichenfolge wird mit einem Alphawert angezeigt, der berechnet wird, indem der transparency Wert von 1 subtrahiert wird:

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

Die WithAlpha Methode legt die Alphakomponente für eine vorhandene Farbe fest, die hier angegeben ist SKColors.Blue. Die zweite Textzeichenfolge verwendet einen Alphawert, der aus dem transparency Wert selbst berechnet wird:

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

Die Animation wechselt zwischen den beiden Wörtern und fordert den Benutzer auf , "mehr Code" anzufordern (oder vielleicht "mehr Code" anzufordern):

Code für weitere Code

Im vorherigen Artikel zu Bitmap Basics in SkiaSharp haben Sie gesehen, wie Sie Bitmaps mit einer der DrawBitmap Methoden von SKCanvas. DrawBitmap Alle Methoden enthalten ein SKPaint Objekt als letzten Parameter. Dieser Parameter ist standardmäßig auf diesen Parameter festgelegt null , und Sie können ihn ignorieren.

Alternativ können Sie die Color Eigenschaft dieses SKPaint Objekts so festlegen, dass eine Bitmap mit einer gewissen Transparenz angezeigt wird. Wenn Sie eine Transparenzstufe in der Color Eigenschaft SKPaint festlegen, können Sie Bitmaps ein- und ausblenden oder eine Bitmap in eine andere auflösen.

Bitmaptransparenz wird auf der Bitmap-Auflösungsseite veranschaulicht. Die XAML-Datei instanziiert eine SKCanvasView und eine 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>

Die CodeBehind-Datei lädt zwei Bitmapressourcen. Diese Bitmaps sind nicht die gleiche Größe, sie sind jedoch das gleiche Seitenverhältnis:

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

Die Color Eigenschaft des SKPaint Objekts wird auf zwei ergänzende Alphaebenen für die beiden Bitmaps festgelegt. Bei verwendung SKPaint mit Bitmaps spielt es keine Rolle, was der Rest des Color Werts ist. Alles, was wichtig ist, ist der Alphakanal. Der Code hier ruft einfach die WithAlpha Methode für den Standardwert der Color Eigenschaft auf.

Verschieben der Slider Auflösungen zwischen einer Bitmap und der anderen:

Bitmap auflösen

In den vergangenen Artikeln haben Sie gesehen, wie Sie Mit SkiaSharp Text, Kreise, Auslassungspunkte, abgerundete Rechtecke und Bitmaps zeichnen können. Der nächste Schritt ist SkiaSharp Lines and Paths , in dem Sie erfahren, wie Sie verbundene Linien in einem Grafikpfad zeichnen.