Xamarin.Forms との統合

Download Sampleサンプルのダウンロード

タッチと Xamarin.Forms 要素に応答する SkiaSharp グラフィックスを作成する

SkiaSharp グラフィックスは、いくつかの方法で残りの Xamarin.Forms 部分と統合できます。 同じページ上で SkiaSharp キャンバスと Xamarin.Forms の要素を組み合わせ、SkiaSharp キャンバスの上に Xamarin.Forms 要素を配置することもできます。

Selecting a color with sliders

Xamarin.Forms でインタラクティブな SkiaSharp グラフィックスを作成するもう 1 つの方法は、タッチ操作です。 SkiaSharpFormsDemos プログラムの 2 番目のページには、「塗りつぶしの切り替え」というタイトルが付いています。 これは、2 つの方法 (塗りつぶしなしと塗りつぶし) で単純な円を描きます。タップで切り替えます。 TapToggleFillPage クラスは、ユーザー入力に応じて SkiaSharp グラフィックスを変更する方法を示しています。

このページでは、SKCanvasView クラスは TapToggleFill.xaml ファイルでインスタンス化され、ビューにも Xamarin.FormsTapGestureRecognizer が設定されます。

<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>

skia XML 名前空間宣言に注意してください。

TapGestureRecognizer オブジェクトの Tapped ハンドラーは、ブール型フィールドの値を切り替え、SKCanvasViewInvalidateSurface メソッドを呼び出します。

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

InvalidateSurface ハンドラーへの呼び出しを効果的に生成する PaintSurface 呼び出し。この呼び出しでは、showFill フィールドを使用して円を塗りつぶすか塗りつぶさないようにします。

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

この StrokeWidth プロパティは、違いを強調するために 50 に設定されています。 また、最初に内部を描画し、次にアウトラインを描画することで、線の幅全体を確認することもできます。 既定では、PaintSurface イベント ハンドラーの後半で描画されるグラフィックス図形は、ハンドラーで前に描画されたものを隠します。

[カラー エクスプローラー] ページでは、SkiaSharp グラフィックスを他の Xamarin.Forms 要素と統合する方法を示し、SkiaSharp で色を定義するための 2 つの代替方法の違いを示します。 静的 SKColor.FromHsl メソッドは、HSL (色相値 - 彩度値 - 輝度値) モデルに基づいて SKColor 値を作成します。

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

静的 SKColor.FromHsv メソッドは、同様の HSV (色相値 - 彩度値 - 値) モデルに基づいて SKColor 値を作成します。

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

どちらの場合も、h 引数の範囲は 0 から 360 です。 sl、および v 引数の範囲は 0 から 100 です。 a (アルファまたは不透明度) 引数の範囲は 0 から 255 です。

ColorExplorePage.xaml ファイルは、StackLayout の 2 つの SKCanvasView オブジェクトを Slider と並べて作成し、ユーザーが HSL と HSV の色値を選択できるようにする Label ビューを作成します。

<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>

2 つの SKCanvasView 要素は、結果として得られる RGB カラー値を表示するために Label 上部に配置された、単一の Grid セル内にあります。

ColorExplorePage.xaml.cs 分離コード ファイルは比較的単純です。 3 つの Slider 要素の共有 ValueChanged ハンドラーは、単に両方の SKCanvasView 要素を無効にします。 PaintSurface ハンドラーは、Slider 要素によって示される色でキャンバスをクリアし、SKCanvasView 要素の上部に配置された Label を設定します。

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

HSL カラーモデルと HSV カラーモデルの両方で、色相値の範囲は 0 から 360 で、色の主要な色合いを示します。 虹の伝統的な色は、赤、オレンジ、黄、緑、青、藍、紫であり、円を描くように赤に戻ります。

HSL モデルでは、輝度値が 0 の場合は常に黒、100 の場合は常に白となります。 彩度値が 0 の場合、輝度値が 0 から 100 の間であれば、灰色の濃淡になります。 彩度を上げると、色が鮮やかになります。 純色 (RGB 値の 1 つのコンポーネントが 255、もう 1 つが 0、残りの 1 つが 0 から 255 の範囲にある色) は、彩度が 100 で輝度が 50 の場合に得られます。

HSV モデルでは、彩度と値の両方が 100 の場合に純色が得られます。 値が 0 の場合、他の設定に関係なく、色は黒になります。 灰色の濃淡は、彩度が 0 で値の範囲が 0 から 100 の場合に得られます。

しかし、2 つのモデルの特性を理解する最善の方法は、自分で実験してみることです。

Triple screenshot of the Color Explore page