Share via


Integration mit Xamarin.Forms

Erstellen von SkiaSharp-Grafiken, die auf Toucheingabe und Xamarin.Forms Elemente reagieren

SkiaSharp-Grafiken können auf verschiedene Arten in den Rest Xamarin.Forms integriert werden. Sie können eine SkiaSharp-Canvas und Xamarin.Forms Elemente auf derselben Seite kombinieren und sogar Elemente über einem SkiaSharp-Zeichenbereich positionieren Xamarin.Forms :

Auswählen einer Farbe mit Schiebereglern

Ein weiterer Ansatz zum Erstellen interaktiver SkiaSharp-Grafiken Xamarin.Forms ist die Toucheingabe.

Die zweite Seite im Beispielprogramm hat den Titel "Füllung umschalten". Es zeichnet einen einfachen Kreis auf zwei Arten – ohne Füllung und mit einer Füllung – um ein Tippen. Die TapToggleFillPage Klasse zeigt, wie Sie SkiaSharp-Grafiken als Reaktion auf Benutzereingaben ändern können.

Für diese Seite wird die SKCanvasView Klasse in der Datei TapToggleFill.xaml instanziiert, die auch eine Xamarin.FormsTapGestureRecognizer in der Ansicht festlegt:

<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.TapToggleFillPage"
             Title="Tap Toggle Fill">

    <skia:SKCanvasView PaintSurface="OnCanvasViewPaintSurface">
        <skia:SKCanvasView.GestureRecognizers>
            <TapGestureRecognizer Tapped="OnCanvasViewTapped" />
        </skia:SKCanvasView.GestureRecognizers>
    </skia:SKCanvasView>
</ContentPage>

Beachten Sie die skia XML-Namespacedeklaration.

Der Tapped Handler für das TapGestureRecognizer Objekt schaltet einfach den Wert eines booleschen Felds um und ruft die InvalidateSurface Methode von SKCanvasView:

bool showFill = true;
...
void OnCanvasViewTapped(object sender, EventArgs args)
{
    showFill ^= true;
    (sender as SKCanvasView).InvalidateSurface();
}

Der Aufruf, um InvalidateSurface effektiv einen Aufruf des PaintSurface Handlers zu generieren, der das showFill Feld verwendet, um den Kreis auszufüllen oder nicht zu füllen:

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

    canvas.Clear();

    SKPaint paint = new SKPaint
    {
        Style = SKPaintStyle.Stroke,
        Color = Color.Red.ToSKColor(),
        StrokeWidth = 50
    };
    canvas.DrawCircle(info.Width / 2, info.Height / 2, 100, paint);

    if (showFill)
    {
        paint.Style = SKPaintStyle.Fill;
        paint.Color = SKColors.Blue;
        canvas.DrawCircle(info.Width / 2, info.Height / 2, 100, paint);
    }
}

Die StrokeWidth Eigenschaft wurde auf 50 festgelegt, um den Unterschied hervorzuheben. Sie können auch die gesamte Linienbreite sehen, indem Sie zuerst den Innenbereich und dann die Kontur zeichnen. Grafiken, die später im PaintSurface Ereignishandler gezeichnet werden, verdecken standardmäßig diejenigen, die weiter oben im Handler gezeichnet wurden.

Auf der Seite "Farbsuche" wird veranschaulicht, wie Sie Auch SkiaSharp-Grafiken in andere Xamarin.Forms Elemente integrieren können. Außerdem wird der Unterschied zwischen zwei alternativen Methoden zum Definieren von Farben in SkiaSharp veranschaulicht. Die statische SKColor.FromHsl Methode erstellt einen SKColor Wert basierend auf dem Hue-Saturation-Lightness-Modell:

public static SKColor FromHsl (Single h, Single s, Single l, Byte a)

Die statische SKColor.FromHsv Methode erstellt einen SKColor Wert basierend auf dem ähnlichen Hue-Saturation-Value-Modell:

public static SKColor FromHsv (Single h, Single s, Single v, Byte a)

In beiden Fällen liegt das h Argument zwischen 0 und 360. Die Argumente und lv Argumente sreichen von 0 bis 100. Das a Argument (Alpha oder Deckkraft) liegt zwischen 0 und 255.

Die Datei ColorExplorePage.xaml erstellt zwei SKCanvasView Objekte StackLayout nebeneinander mit Slider und Label Ansichten, mit denen der Benutzer HSL- und HSV-Farbwerte auswählen kann:

<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.Basics.ColorExplorePage"
             Title="Color Explore">
    <StackLayout>
        <!-- Hue slider -->
        <Slider x:Name="hueSlider"
                Maximum="360"
                Margin="20, 0"
                ValueChanged="OnSliderValueChanged" />

        <Label HorizontalTextAlignment="Center"
               Text="{Binding Source={x:Reference hueSlider},
                              Path=Value,
                              StringFormat='Hue = {0:F0}'}" />

        <!-- Saturation slider -->
        <Slider x:Name="saturationSlider"
                Maximum="100"
                Margin="20, 0"
                ValueChanged="OnSliderValueChanged" />

        <Label HorizontalTextAlignment="Center"
               Text="{Binding Source={x:Reference saturationSlider},
                              Path=Value,
                              StringFormat='Saturation = {0:F0}'}" />

        <!-- Lightness slider -->
        <Slider x:Name="lightnessSlider"
                Maximum="100"
                Margin="20, 0"
                ValueChanged="OnSliderValueChanged" />

        <Label HorizontalTextAlignment="Center"
               Text="{Binding Source={x:Reference lightnessSlider},
                              Path=Value,
                              StringFormat='Lightness = {0:F0}'}" />

        <!-- HSL canvas view -->
        <Grid VerticalOptions="FillAndExpand">
            <skia:SKCanvasView x:Name="hslCanvasView"
                               PaintSurface="OnHslCanvasViewPaintSurface" />

            <Label x:Name="hslLabel"
                   HorizontalOptions="Center"
                   VerticalOptions="Center"
                   BackgroundColor="Black"
                   TextColor="White" />
        </Grid>

        <!-- Value slider -->
        <Slider x:Name="valueSlider"
                Maximum="100"
                Margin="20, 0"
                ValueChanged="OnSliderValueChanged" />

        <Label HorizontalTextAlignment="Center"
               Text="{Binding Source={x:Reference valueSlider},
                              Path=Value,
                              StringFormat='Value = {0:F0}'}" />

        <!-- HSV canvas view -->
        <Grid VerticalOptions="FillAndExpand">
            <skia:SKCanvasView x:Name="hsvCanvasView"
                               PaintSurface="OnHsvCanvasViewPaintSurface" />

            <Label x:Name="hsvLabel"
                   HorizontalOptions="Center"
                   VerticalOptions="Center"
                   BackgroundColor="Black"
                   TextColor="White" />
        </Grid>
    </StackLayout>
</ContentPage>

Die beiden SKCanvasView Elemente befinden sich in einer einzelnen Zelle Grid mit einer Label sitzenden Zelle oben, um den resultierenden RGB-Farbwert anzuzeigen.

Die ColorExplorePage.xaml.cs CodeBehind-Datei ist relativ einfach. Der freigegebene ValueChanged Handler für die drei Slider Elemente ungültigt einfach beide SKCanvasView Elemente. Die PaintSurface Handler löschen den Zeichenbereich mit der Farbe, die durch die Slider Elemente angegeben wird, und legen sie außerdem auf Label die Sitzenden über den SKCanvasView Elementen fest:

public partial class ColorExplorePage : ContentPage
{
    public ColorExplorePage()
    {
        InitializeComponent();

        hueSlider.Value = 0;
        saturationSlider.Value = 100;
        lightnessSlider.Value = 50;
        valueSlider.Value = 100;
    }

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

    void OnHslCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
    {
        SKColor color = SKColor.FromHsl((float)hueSlider.Value,
                                        (float)saturationSlider.Value,
                                        (float)lightnessSlider.Value);
        args.Surface.Canvas.Clear(color);

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

    void OnHsvCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
    {
        SKColor color = SKColor.FromHsv((float)hueSlider.Value,
                                        (float)saturationSlider.Value,
                                        (float)valueSlider.Value);
        args.Surface.Canvas.Clear(color);

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

In den Farbmodellen HSL und HSV reicht der Farbtonwert von 0 bis 360 und gibt den dominanten Farbton an. Dies sind die traditionellen Farben des Regenbogens: Rot, Orange, Gelb, Grün, Blau, Indigo, Violett und zurück in einem Kreis zu Rot.

Im HSL-Modell ist ein 0-Wert für "Lichtheit" immer schwarz, und ein Wert von 100 ist immer weiß. Wenn der Sättigungswert 0 ist, sind Helligkeitswerte zwischen 0 und 100 Graustufen. Durch das Erhöhen der Sättigung wird mehr Farbe hinzugefügt. Reine Farben (die RGB-Werte mit einer Komponente gleich 255, ein anderer gleich 0 und der dritte Bereich von 0 bis 255) treten auf, wenn die Sättigung 100 ist und die Helligkeit 50 ist.

Im HSV-Modell ergeben sich reine Farben, wenn sowohl die Sättigung als auch der Wert 100 sind. Wenn Der Wert 0 ist, unabhängig von anderen Einstellungen, ist die Farbe schwarz. Grautöne treten auf, wenn die Sättigung 0 ist und der Wert zwischen 0 und 100 liegt.

Aber die beste Möglichkeit, ein Gefühl für die beiden Modelle zu bekommen, besteht darin, mit ihnen selbst zu experimentieren:

Dreifacher Screenshot der Seite