SkiaSharp の透明度
これまでに説明したように、SKPaint
クラスには SKColor
型の Color
プロパティが含まれています。 SKColor
にはアルファ チャネルが含まれているため、SKColor
値で色分けするものは部分的に透明にすることができます。
一部の透明度は、SkiaSharp の基本アニメーションに関する記事で説明されています。 この記事では、1 つのシーンで複数のオブジェクトを結合する透明度について詳しく説明します。これは、ブレンドとも呼ばれる手法です。 より高度なブレンド手法については、「SkiaSharp シェーダー」セクションの記事で説明します。
透明度レベルは、最初に 4 つのパラメーター SKColor
コンストラクターを使用して色を作成するときに設定できます。
SKColor (byte red, byte green, byte blue, byte alpha);
アルファ値 0 は完全に透明で、アルファ値 0xFF は完全に不透明です。 これら 2 つの両極端な値の間では、部分的に透明な色が作成されます。
さらに、SKColor
は既存の色から新しい色を作成するのに便利な WithAlpha
メソッドを定義しますが、アルファ レベルは指定されています。
SKColor halfTransparentBlue = SKColors.Blue.WithAlpha(0x80);
部分的に透明なテキストの使用については、サンプルの [詳細なコード] ページで説明しています。 このページでは、SKColor
値に透明度を組み込むことで、2 つのテキスト文字列をフェード イン/アウトします。
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);
}
}
}
transparency
フィールドは 0 から 1 まで変化するようにアニメーション化され、正弦波のリズムでもう一度元に戻ります。 最初のテキスト文字列は、transparency
値を 1 から減算して計算されたアルファ値で表示されます。
paint.Color = SKColors.Blue.WithAlpha((byte)(0xFF * (1 - transparency)));
WithAlpha
メソッドは、既存の色 (こちらでは SKColors.Blue
) にアルファ コンポーネントを設定します。 2 番目のテキスト文字列は、transparency
の値自体から計算されたアルファ値を使用します。
paint.Color = SKColors.Blue.WithAlpha((byte)(0xFF * transparency));
アニメーションは 2 つの単語を交互に使用し、ユーザーに "code more" (または "more code") を要求するよう促します。
前の記事の「SkiaSharp のビットマップの基本」では、SKCanvas
の DrawBitmap
メソッドの 1 つを使用してビットマップを表示する方法を確認しました。 すべての DrawBitmap
メソッドには、最後のパラメーターとして SKPaint
オブジェクトが含まれます。 既定では、このパラメーターは null
に設定され、無視できます。
または、この SKPaint
オブジェクトの Color
プロパティを設定して、ある程度の透明度を持つビットマップを表示することもできます。 SKPaint
の Color
プロパティに透明度のレベルを設定すると、ビットマップをフェードイン/アウトしたり、ビットマップを別のビットマップにディゾルブしたりできます。
ビットマップの透明度は、[ビットマップのディゾルブ] ページで説明されています。 XAML ファイルは、次の SKCanvasView
と 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>
分離コード ファイルは、2 つのビットマップ リソースを読み込みます。 これらのビットマップは同じサイズではありませんが、縦横比は同じです。
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);
}
}
}
SKPaint
オブジェクトの Color
プロパティは、2 つのビットマップの 2 つの補完的なアルファ レベルに設定されます。 ビットマップを含む SKPaint
を使用する場合、Color
値の残りの部分は関係ありません。 重要なのはアルファ チャネルです。 ここでのコードは、Color
プロパティの既定値で WithAlpha
メソッドを呼び出すだけです。
Slider
を移動させると、1 つのビットマップともう一方のビットマップの間でディゾルブします。
過去のいくつかの記事では、SkiaSharp を使用してテキスト、円、楕円、角丸四角形、ビットマップを描画する方法について説明しました。 次の手順は SkiaSharp の線とパスで、グラフィックス パスに接続された線を描画する方法を学習します。