次の方法で共有


SkiaSharp ビットマップの表示

SkiaSharp ビットマップに関する主題は、SkiaSharp のビットマップの基本に関する記事で紹介しました。 その記事では、ビットマップを読み込む 3 つの方法とビットマップを表示する 3 つの方法を示しました。 この記事では、ビットマップを読み込む手法を確認し、SKCanvasDrawBitmap メソッドの使用について深く掘り下げます。

サンプルの表示

DrawBitmapLattice および DrawBitmapNinePatch メソッドについては、SkiaSharp ビットマップのセグメント化された表示に関する記事で説明します。

このページのサンプルは、サンプル アプリケーションからのものです。 そのアプリケーションのホーム ページで、[SkiaSharp ビットマップ] を選択し、[ビットマップの表示] セクションに移動します。

ビットマップの読み込み

SkiaSharp アプリケーションで使用されるビットマップは通常、次の 3 つの異なるソースのいずれかから取得されます。

  • インターネットから
  • 実行可能ファイルに埋め込まれているリソースから
  • ユーザーの写真ライブラリから

SkiaSharp アプリケーションで新しいビットマップを作成し、その上に描画したり、ビットマップ ビットをアルゴリズムで設定したりすることもできます。 これらの手法については、SkiaSharp ビットマップの作成と描画SkiaSharp ビットマップ ピクセルへのアクセスに関する記事で説明されています。

ビットマップを読み込む次の 3 つのコード例では、クラスにタイプ SKBitmap のフィールドが含まれていることを前提としています。

SKBitmap bitmap;

SkiaSharp のビットマップの基本に関する記事で説明したように、インターネット経由でビットマップを読み込む最善の方法は HttpClient クラスを使用する方法です。 クラスの 1 つのインスタンスをフィールドとして定義できます。

HttpClient httpClient = new HttpClient();

iOS および Android アプリケーションで HttpClient を使用する場合は、トランスポート層セキュリティ (TLS) 1.2 のドキュメントの説明に従って、プロジェクトのプロパティを設定する必要があります。

多くの場合、HttpClient を使用するコードには await 演算子が含まれるため、このコードは async メソッド内に存在する必要があります。

try
{
    using (Stream stream = await httpClient.GetStreamAsync("https:// ··· "))
    using (MemoryStream memStream = new MemoryStream())
    {
        await stream.CopyToAsync(memStream);
        memStream.Seek(0, SeekOrigin.Begin);

        bitmap = SKBitmap.Decode(memStream);
        ···
    };
}
catch
{
    ···
}

GetStreamAsync から取得した Stream オブジェクトが MemoryStream にコピーされることに注意してください。 Android では、非同期メソッドでの場合を除き、メイン スレッドによって HttpClientStream が処理されることは許可されません。

SKBitmap.Decode は多くの処理を行います。これに渡された Stream オブジェクトは、ビットマップ全体が一般的なビットマップ ファイル形式 (通常は JPEG、PNG、GIF) のいずれかで含まれるメモリ ブロックを参照します。 Decode メソッドは、形式を確認してから、ビットマップ ファイルを SkiaSharp 独自の内部ビットマップ形式にデコードする必要があります。

コードは、SKBitmap.Decode を呼び出した後、たいていは CanvasView を無効にし、PaintSurface ハンドラーが新しく読み込まれたビットマップを表示できるようにします。

ビットマップを読み込む 2 番目の方法は、個々のプラットフォーム プロジェクトによって参照される .NET Standard ライブラリにビットマップを埋め込みリソースとして含める方法です。 GetManifestResourceStream メソッドにはリソース ID が渡されます。 このリソース ID は、ピリオドで区切られたリソースのアセンブリ名、フォルダー名、ファイル名で構成されます。

string resourceID = "assemblyName.folderName.fileName";
Assembly assembly = GetType().GetTypeInfo().Assembly;

using (Stream stream = assembly.GetManifestResourceStream(resourceID))
{
    bitmap = SKBitmap.Decode(stream);
    ···
}

ビットマップ ファイルは、iOS、Android、ユニバーサル Windows プラットフォーム (UWP) の個々のプラットフォーム プロジェクトにリソースとして格納することもできます。 ただし、これらのビットマップを読み込むには、プラットフォーム プロジェクトにあるコードが必要です。

ビットマップを取得する 3 番目の方法は、ユーザーの画像ライブラリから取得する方法です。 次のコードでは、サンプル アプリケーションに含まれている依存関係サービスを使用します。 SkiaSharpFormsDemo .NET Standard ライブラリには IPhotoLibrary インターフェイスが含まれていますが、各プラットフォーム プロジェクトには、そのインターフェイスを実装する PhotoLibrary クラスが含まれています。

IPhotoicturePicker picturePicker = DependencyService.Get<IPhotoLibrary>();

using (Stream stream = await picturePicker.GetImageStreamAsync())
{
    if (stream != null)
    {
        bitmap = SKBitmap.Decode(stream);
        ···
    }
}

一般に、このようなコードは、CanvasView を無効にし、PaintSurface ハンドラーが新しいビットマップを表示できるようにします。

SKBitmap クラスは、ビットマップのピクセルの寸法を明らかにする WidthHeight を含む複数の便利なプロパティや、ビットマップの作成、ビットマップのコピー、ピクセル ビットの公開などを行うメソッドを含む多くのメソッドを定義します。

ピクセルの寸法での表示

SkiaSharp の Canvas クラスは、4 つの DrawBitmap メソッドを定義します。 これらのメソッドを使用すると、基本的に異なる 2 つの方法でビットマップを表示できます。

  • SKPoint 値 (または個別の x および y 値) を指定すると、ビットマップがピクセルの寸法で表示されます。 ビットマップのピクセルは、ビデオ ディスプレイのピクセルに直接マップされます。
  • 四角形を指定すると、ビットマップは四角形のサイズと形状に引き伸ばされます。

ビットマップをピクセルの寸法ンションで表示するには、DrawBitmapSKPoint パラメータと共に使用するか、DrawBitmap を別個の x および y パラメーターと共に使用します。

DrawBitmap(SKBitmap bitmap, SKPoint pt, SKPaint paint = null)

DrawBitmap(SKBitmap bitmap, float x, float y, SKPaint paint = null)

これら 2 つのメソッドは機能的に同じです。 指定した点は、キャンバスを基準としたビットマップの左上の角の位置を示します。 モバイル デバイスのピクセル解像度は非常に高いため、通常、これらのデバイスでは小さいビットマップが非常に小さく表示されます。

省略可能な SKPaint パラメータを使用すると、透明度を使用してビットマップを表示できます。 これを行うには、SKPaint オブジェクトを作成し、Color プロパティを、アルファ チャネルが 1 未満である任意 SKColor の値に設定します。 次に例を示します。

paint.Color = new SKColor(0, 0, 0, 0x80);

最後の引数として渡された 0x80 は、50% の透明度を示します。 また、定義済みの色のいずれかにアルファ チャネルを設定することもできます。

paint.Color = SKColors.Red.WithAlpha(0x80);

ただし、色自体は関係ありません。 DrawBitmap 呼び出しで SKPaint オブジェクトを使用すると、アルファ チャネルのみが調べられます。

また、ブレンド モードまたはフィルター効果を使用してビットマップを表示する場合、SKPaint オブジェクトも役割を果たします。 これらは、SkiaSharp の合成モードとブレンド モードおよび SkiaSharp 画像フィルターに関する記事で説明されています。

サンプル プログラムの Pixel Dimensions ページには、幅 320 ピクセル x 高さ 240 ピクセルのビットマップ リソースが表示されます。

public class PixelDimensionsPage : ContentPage
{
    SKBitmap bitmap;

    public PixelDimensionsPage()
    {
        Title = "Pixel Dimensions";

        // Load the bitmap from a resource
        string resourceID = "SkiaSharpFormsDemos.Media.Banana.jpg";
        Assembly assembly = GetType().GetTypeInfo().Assembly;

        using (Stream stream = assembly.GetManifestResourceStream(resourceID))
        {
            bitmap = SKBitmap.Decode(stream);
        }

        // Create the SKCanvasView and set the PaintSurface handler
        SKCanvasView canvasView = new SKCanvasView();
        canvasView.PaintSurface += OnCanvasViewPaintSurface;
        Content = canvasView;
    }

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

        canvas.Clear();

        float x = (info.Width - bitmap.Width) / 2;
        float y = (info.Height - bitmap.Height) / 2;

        canvas.DrawBitmap(bitmap, x, y);
    }
}

PaintSurface ハンドラーは、ディスプレイ面のピクセルの寸法とビットマップのピクセルの寸法に基づいて x および y 値を計算して、ビットマップを中央に配置します。

ピクセル ディメンション

アプリケーションは、左上の角にビットマップを表示する必要がある場合、単に (0, 0) の座標を渡します。

リソース ビットマップを読み込むためのメソッド

後続のサンプルの多くでは、ビットマップ リソースを読み込む必要があります。 サンプル ソリューションの静的 BitmapExtensions クラスには、次の役立つ方法が含まれています。

static class BitmapExtensions
{
    public static SKBitmap LoadBitmapResource(Type type, string resourceID)
    {
        Assembly assembly = type.GetTypeInfo().Assembly;

        using (Stream stream = assembly.GetManifestResourceStream(resourceID))
        {
            return SKBitmap.Decode(stream);
        }
    }
    ···
}

Type パラメータに注目してください。 これは、ビットマップ リソースを格納する Type アセンブリ内の任意の型に関連付けられたオブジェクトである場合があります。

この LoadBitmapResource メソッドは、ビットマップ リソースを必要とする後続のすべてのサンプルで使用されます。

四角形を塗りつぶすために引き伸ばす

SKCanvas クラスは、ビットマップを四角形にレンダリングする DrawBitmap メソッドと、ビットマップの四角形のサブセットを四角形にレンダリングする別の DrawBitmap メソッドも定義します。

DrawBitmap(SKBitmap bitmap, SKRect dest, SKPaint paint = null)

DrawBitmap(SKBitmap bitmap, SKRect source, SKRect dest, SKPaint paint = null)

どちらの場合も、ビットマップは、dest という名前の四角形を塗りつぶすために引き伸ばされます。 2 番目のメソッドでは、source 四角形を使用してビットマップのサブセットを選択できます。 dest 四角形は出力デバイスを基準としており、source 四角形はビットマップを基準としています。

Fill Rectangle ページは、キャンバスと同じサイズの四角形の前の例で使用したものと同じビットマップを表示することで、これら 2 つのメソッドの最初のメソッドを示します。

public class FillRectanglePage : ContentPage
{
    SKBitmap bitmap =
        BitmapExtensions.LoadBitmapResource(typeof(FillRectanglePage),
                                            "SkiaSharpFormsDemos.Media.Banana.jpg");
    public FillRectanglePage ()
    {
        Title = "Fill Rectangle";

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

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

        canvas.Clear();

        canvas.DrawBitmap(bitmap, info.Rect);
    }
}

新しい BitmapExtensions.LoadBitmapResource メソッドを使用して SKBitmap フィールドを設定していることに注意してください。 変換先の四角形は、ディスプレイ面のサイズを説明する SKImageInfoRect プロパティから取得されます。

四角形の塗りつぶし

これは通常、望ましくありません。 この画像は、水平方向と垂直方向に異なる方法で引き伸ばされて歪んでいます。 ビットマップをピクセル サイズ以外の方法で表示する場合は通常、ビットマップの元の縦横比を維持する必要があります。

縦横比を維持しながら引き伸ばす

縦横比を維持しながらビットマップを引き伸ばすことは、均一スケーリングとも呼ばれるプロセスです。 この用語は、アルゴリズム アプローチを示唆しています。 考えられる解決策の 1 つは、Uniform Scaling ページに示されています。

public class UniformScalingPage : ContentPage
{
    SKBitmap bitmap =
        BitmapExtensions.LoadBitmapResource(typeof(UniformScalingPage),
                                            "SkiaSharpFormsDemos.Media.Banana.jpg");
    public UniformScalingPage()
    {
        Title = "Uniform Scaling";

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

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

        canvas.Clear();

        float scale = Math.Min((float)info.Width / bitmap.Width,
                               (float)info.Height / bitmap.Height);
        float x = (info.Width - scale * bitmap.Width) / 2;
        float y = (info.Height - scale * bitmap.Height) / 2;
        SKRect destRect = new SKRect(x, y, x + scale * bitmap.Width,
                                           y + scale * bitmap.Height);

        canvas.DrawBitmap(bitmap, destRect);
    }
}

PaintSurface ハンドラーは、ビットマップの幅と高さに対するディスプレイの幅と高さの比率の最小値である scale 係数を計算します。 その後、スケーリングされたビットマップをディスプレイの幅と高さの範囲内に中央揃えするために、x および y 値を計算できます。 変換先の四角形には、x および y の左上の角と、これらの値の右下の角に加えて、スケーリングされたビットマップの幅と高さがあります。

均一スケーリング

スマートフォンを横向きにして、ビットマップがその領域まで引き伸ばされていることを確認します。

横向きの均一スケーリング

この scale 係数を使用する利点は、若干異なるアルゴリズムを実装するときに明らかになります。 ビットマップの縦横比を維持するが、変換先の四角形も塗りつぶしたいとします。 これが可能な唯一の方法は、画像の一部をトリミングすることですが、上記のコードで Math.MinMath.Max に変更するだけでこのアルゴリズムを実装できます。 結果は次のとおりです。

別の向きの均一スケーリング

ビットマップの縦横比は保持されますが、ビットマップの左右の領域はトリミングされます。

汎用性の高いビットマップ表示関数

XAML ベースのプログラミング環境 (UWP や Xamarin.Forms など) には、ビットマップのサイズを拡大または縮小しながら縦横比を維持するための機能があります。 SkiaSharp にはこの機能は含まれませんが、自分で実装できます。

サンプル アプリケーションに含まれる BitmapExtensions クラスは、その方法を示しています。 このクラスは、縦横比の計算を実行する 2 つの新しい DrawBitmap メソッドを定義します。 これらの新しいメソッドは、SKCanvas の拡張メソッドです。

この新しい DrawBitmap メソッドには、BitmapExtensions.cs ファイルに定義されている列挙型である、タイプ BitmapStretch のパラメータが含まれます。

public enum BitmapStretch
{
    None,
    Fill,
    Uniform,
    UniformToFill,
    AspectFit = Uniform,
    AspectFill = UniformToFill
}

NoneFillUniformUniformToFill メンバーは、UWP の Stretch 列挙型のメンバーと同じです。 同様の Xamarin.FormsAspect 列挙型は、メンバー FillAspectFitAspectFill を定義します。

上記の Uniform Scaling ページではビットマップは四角形内に中央揃えされます。しかし、ビットマップを四角形の左側または右側、上側または下側に配置するなど、その他のオプションが必要な場合があります。 これが BitmapAlignment メソッドの目的です。

public enum BitmapAlignment
{
    Start,
    Center,
    End
}

配置設定は、BitmapStretch.Fill と一緒に使用すると、効果がありません。

最初の DrawBitmap 拡張関数には、変換先の四角形が含まれますが、変換元の四角形は含まれません。 既定では、ビットマップを中央揃えにする必要があるときに、BitmapStretch メンバーのみを指定する必要があるよう定義されています。

static class BitmapExtensions
{
    ···
    public static void DrawBitmap(this SKCanvas canvas, SKBitmap bitmap, SKRect dest,
                                  BitmapStretch stretch,
                                  BitmapAlignment horizontal = BitmapAlignment.Center,
                                  BitmapAlignment vertical = BitmapAlignment.Center,
                                  SKPaint paint = null)
    {
        if (stretch == BitmapStretch.Fill)
        {
            canvas.DrawBitmap(bitmap, dest, paint);
        }
        else
        {
            float scale = 1;

            switch (stretch)
            {
                case BitmapStretch.None:
                    break;

                case BitmapStretch.Uniform:
                    scale = Math.Min(dest.Width / bitmap.Width, dest.Height / bitmap.Height);
                    break;

                case BitmapStretch.UniformToFill:
                    scale = Math.Max(dest.Width / bitmap.Width, dest.Height / bitmap.Height);
                    break;
            }

            SKRect display = CalculateDisplayRect(dest, scale * bitmap.Width, scale * bitmap.Height,
                                                  horizontal, vertical);

            canvas.DrawBitmap(bitmap, display, paint);
        }
    }
    ···
}

このメソッドの主な目的は、scale という名前のスケーリング係数を計算することです。この係数はその後、CalculateDisplayRect メソッドを呼び出すときにビットマップの幅と高さに適用されます。 これは、水平方向と垂直方向の配置に基づいてビットマップを表示するための四角形を計算するメソッドです。

static class BitmapExtensions
{
    ···
    static SKRect CalculateDisplayRect(SKRect dest, float bmpWidth, float bmpHeight,
                                       BitmapAlignment horizontal, BitmapAlignment vertical)
    {
        float x = 0;
        float y = 0;

        switch (horizontal)
        {
            case BitmapAlignment.Center:
                x = (dest.Width - bmpWidth) / 2;
                break;

            case BitmapAlignment.Start:
                break;

            case BitmapAlignment.End:
                x = dest.Width - bmpWidth;
                break;
        }

        switch (vertical)
        {
            case BitmapAlignment.Center:
                y = (dest.Height - bmpHeight) / 2;
                break;

            case BitmapAlignment.Start:
                break;

            case BitmapAlignment.End:
                y = dest.Height - bmpHeight;
                break;
        }

        x += dest.Left;
        y += dest.Top;

        return new SKRect(x, y, x + bmpWidth, y + bmpHeight);
    }
}

この BitmapExtensions クラスには、追加の DrawBitmap メソッドと共に、ビットマップのサブセットを指定するための変換元の四角形が含まれています。 このメソッドは最初のメソッドと似ていますが、スケーリング係数が source 四角形に基づいて計算された後、CalculateDisplayRect に対する呼び出し内の source 四角形に適用される点が異なります。

static class BitmapExtensions
{
    ···
    public static void DrawBitmap(this SKCanvas canvas, SKBitmap bitmap, SKRect source, SKRect dest,
                                  BitmapStretch stretch,
                                  BitmapAlignment horizontal = BitmapAlignment.Center,
                                  BitmapAlignment vertical = BitmapAlignment.Center,
                                  SKPaint paint = null)
    {
        if (stretch == BitmapStretch.Fill)
        {
            canvas.DrawBitmap(bitmap, source, dest, paint);
        }
        else
        {
            float scale = 1;

            switch (stretch)
            {
                case BitmapStretch.None:
                    break;

                case BitmapStretch.Uniform:
                    scale = Math.Min(dest.Width / source.Width, dest.Height / source.Height);
                    break;

                case BitmapStretch.UniformToFill:
                    scale = Math.Max(dest.Width / source.Width, dest.Height / source.Height);
                    break;
            }

            SKRect display = CalculateDisplayRect(dest, scale * source.Width, scale * source.Height,
                                                  horizontal, vertical);

            canvas.DrawBitmap(bitmap, source, display, paint);
        }
    }
    ···
}

これら 2 つの新しい DrawBitmap メソッドの 1 つ目は、Scaling Modes ページで説明されています。 XAML ファイルには、BitmapStretch および BitmapAlignment 列挙型のメンバーを選択できる 3 つの Picker 要素が含まれています。

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:SkiaSharpFormsDemos"
             xmlns:skia="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms"
             x:Class="SkiaSharpFormsDemos.Bitmaps.ScalingModesPage"
             Title="Scaling Modes">

    <Grid Padding="10">
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>

        <skia:SKCanvasView x:Name="canvasView"
                           Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"
                           PaintSurface="OnCanvasViewPaintSurface" />

        <Label Text="Stretch:"
               Grid.Row="1" Grid.Column="0"
               VerticalOptions="Center" />

        <Picker x:Name="stretchPicker"
                Grid.Row="1" Grid.Column="1"
                SelectedIndexChanged="OnPickerSelectedIndexChanged">
            <Picker.ItemsSource>
                <x:Array Type="{x:Type local:BitmapStretch}">
                    <x:Static Member="local:BitmapStretch.None" />
                    <x:Static Member="local:BitmapStretch.Fill" />
                    <x:Static Member="local:BitmapStretch.Uniform" />
                    <x:Static Member="local:BitmapStretch.UniformToFill" />
                </x:Array>
            </Picker.ItemsSource>

            <Picker.SelectedIndex>
                0
            </Picker.SelectedIndex>
        </Picker>

        <Label Text="Horizontal Alignment:"
               Grid.Row="2" Grid.Column="0"
               VerticalOptions="Center" />

        <Picker x:Name="horizontalPicker"
                Grid.Row="2" Grid.Column="1"
                SelectedIndexChanged="OnPickerSelectedIndexChanged">
            <Picker.ItemsSource>
                <x:Array Type="{x:Type local:BitmapAlignment}">
                    <x:Static Member="local:BitmapAlignment.Start" />
                    <x:Static Member="local:BitmapAlignment.Center" />
                    <x:Static Member="local:BitmapAlignment.End" />
                </x:Array>
            </Picker.ItemsSource>

            <Picker.SelectedIndex>
                0
            </Picker.SelectedIndex>
        </Picker>

        <Label Text="Vertical Alignment:"
               Grid.Row="3" Grid.Column="0"
               VerticalOptions="Center" />

        <Picker x:Name="verticalPicker"
                Grid.Row="3" Grid.Column="1"
                SelectedIndexChanged="OnPickerSelectedIndexChanged">
            <Picker.ItemsSource>
                <x:Array Type="{x:Type local:BitmapAlignment}">
                    <x:Static Member="local:BitmapAlignment.Start" />
                    <x:Static Member="local:BitmapAlignment.Center" />
                    <x:Static Member="local:BitmapAlignment.End" />
                </x:Array>
            </Picker.ItemsSource>

            <Picker.SelectedIndex>
                0
            </Picker.SelectedIndex>
        </Picker>
    </Grid>
</ContentPage>

分離コード ファイルは、Picker 項目が変更されたときに単に CanvasView を無効にします。 PaintSurface ハンドラーは、DrawBitmap 拡張メソッドを呼び出すための 3 つの Picker ビューにアクセスします。

public partial class ScalingModesPage : ContentPage
{
    SKBitmap bitmap =
        BitmapExtensions.LoadBitmapResource(typeof(ScalingModesPage),
                                            "SkiaSharpFormsDemos.Media.Banana.jpg");
    public ScalingModesPage()
    {
        InitializeComponent();
    }

    private void OnPickerSelectedIndexChanged(object sender, EventArgs args)
    {
        canvasView.InvalidateSurface();
    }

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

        canvas.Clear();

        SKRect dest = new SKRect(0, 0, info.Width, info.Height);

        BitmapStretch stretch = (BitmapStretch)stretchPicker.SelectedItem;
        BitmapAlignment horizontal = (BitmapAlignment)horizontalPicker.SelectedItem;
        BitmapAlignment vertical = (BitmapAlignment)verticalPicker.SelectedItem;

        canvas.DrawBitmap(bitmap, dest, stretch, horizontal, vertical);
    }
}

オプションの組み合わせをいくつか次に示します。

スケーリング モード

Rectangle Subset ページには、Scaling Modes と実質的に同じ XAML ファイルがありますが、分離コード ファイルでは、SOURCE フィールドによって指定されたビットマップの四角形のサブセットが定義されます。

public partial class ScalingModesPage : ContentPage
{
    SKBitmap bitmap =
        BitmapExtensions.LoadBitmapResource(typeof(ScalingModesPage),
                                            "SkiaSharpFormsDemos.Media.Banana.jpg");

    static readonly SKRect SOURCE = new SKRect(94, 12, 212, 118);

    public RectangleSubsetPage()
    {
        InitializeComponent();
    }

    private void OnPickerSelectedIndexChanged(object sender, EventArgs args)
    {
        canvasView.InvalidateSurface();
    }

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

        canvas.Clear();

        SKRect dest = new SKRect(0, 0, info.Width, info.Height);

        BitmapStretch stretch = (BitmapStretch)stretchPicker.SelectedItem;
        BitmapAlignment horizontal = (BitmapAlignment)horizontalPicker.SelectedItem;
        BitmapAlignment vertical = (BitmapAlignment)verticalPicker.SelectedItem;

        canvas.DrawBitmap(bitmap, SOURCE, dest, stretch, horizontal, vertical);
    }
}

次のスクリーンショットに示すように、この四角形の変換元はサルの頭を分離します。

四角形のサブセット