SkiaSharp 투명도

앞에서 본 것처럼 클래스에는 SKPaint 형식SKColor의 속성이 Color 포함됩니다. SKColor 에는 알파 채널이 포함되어 있으므로 값으로 색을 지정하는 SKColor 모든 항목은 부분적으로 투명할 수 있습니다.

SkiaSharp의 기본 애니메이션 문서에서 일부 투명성이 입증되었습니다. 이 문서에서는 여러 개체를 단일 장면에 결합하기 위해 투명도를 좀 더 자세히 설명합니다. 이 기법은 혼합이라고도 합니다. 고급 혼합 기술은 SkiaSharp 셰이더 섹션의 문서에서 설명합니다.

네 매개 변수 SKColor 생성자를 사용하여 색을 처음 만들 때 투명도 수준을 설정할 수 있습니다.

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

알파 값 0은 완전히 투명하며 0xFF 알파 값은 완전히 불투명합니다. 이러한 두 극단 사이의 값은 부분적으로 투명한 색을 만듭니다.

또한 SKColor 지정된 알파 수준을 사용하여 기존 색에서 새 색을 만드는 편리한 WithAlpha 메서드를 정의합니다.

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

부분적으로 투명한 텍스트의 사용은 샘플의 코드 추가 코드 페이지에 설명되어 있습니다. 이 페이지는 값에 투명도를 통합하여 두 개의 텍스트 문자열을 페이드 인/아웃합니다 SKColor .

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까지 다양하고 부비동 리듬으로 다시 애니메이션됩니다. 첫 번째 텍스트 문자열은 1에서 값을 빼서 계산된 transparency 알파 값으로 표시됩니다.

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

이 메서드는 WithAlpha 기존 색 SKColors.Blue에서 알파 구성 요소를 설정합니다. 두 번째 텍스트 문자열은 값 자체에서 계산된 transparency 알파 값을 사용합니다.

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

애니메이션은 두 단어를 번갈아 가며 사용자에게 "더 많은 코드"(또는 "더 많은 코드"를 요청)를 촉구합니다.

코드 추가 코드

SkiaSharp의 Bitmap Basics에 대한 이전 문서에서는 메서드 중 하나를 사용하여 비트맵을 DrawBitmapSKCanvas표시하는 방법을 알아보았습니다. 모든 메서드는 DrawBitmap 개체를 SKPaint 마지막 매개 변수로 포함합니다. 기본적으로 이 매개 변수는 설정 null 되며 무시해도 됩니다.

또는 이 SKPaint 개체의 속성을 설정 Color 하여 일정 수준의 투명도로 비트맵을 표시할 수 있습니다. 속성 SKPaintColor 투명도 수준을 설정하면 비트맵을 페이드 인/아웃하거나 비트맵을 다른 비트맵에 녹일 수 있습니다.

비트맵 투명도는 비트맵 디졸브 페이지에 설명되어 있습니다. 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>

코드 숨김 파일은 두 개의 비트맵 리소스를 로드합니다. 이러한 비트맵의 크기는 같지 않지만 가로 세로 비율은 동일합니다.

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 두 비트맵에 대해 두 개의 보조 알파 수준으로 설정됩니다. 비트맵과 함께 사용하는 SKPaint 경우 나머지 Color 값은 중요하지 않습니다. 중요한 것은 알파 채널입니다. 여기서 코드는 속성의 WithAlpha 기본값에 대해 메서드를 호출하기 Color 만 하면됩니다.

Slider 한 비트맵과 다른 비트맵 간에 용해를 이동합니다.

비트맵 디졸브

과거에는 SkiaSharp을 사용하여 텍스트, 원, 줄임표, 둥근 사각형 및 비트맵을 그리는 방법을 살펴보셨습니다. 다음 단계는 그래픽 경로 에 연결된 선을 그리는 방법을 알아보는 SkiaSharp 선 및 경로입니다.