SkiaSharp 이미지 필터SkiaSharp image filters

샘플 다운로드 샘플 다운로드Download Sample Download the sample

이미지 필터는 픽셀 이미지를 구성 하는 모든 색 비트에서 작동 하는 효과입니다.Image filters are effects that operate on all the color bits of pixels that make up an image. 이 문서에 설명 된 대로 알파 채널 에서만 작동 하는 마스크 필터 보다 더 많은 SkiaSharp 마스크 필터합니다.They are more versatile than mask filters, which only operate on the alpha channel as described in the article SkiaSharp mask filters. 이미지 필터를 사용 하려면 설정 합니다 ImageFilter 속성을 SKPaint 형식의 개체에 SKImageFilter 클래스의 정적 메서드 중 하나를 호출 하 여 만든 합니다.To use an image filter, set the ImageFilter property of SKPaint to an object of type SKImageFilter that you've created by calling one of the class's static methods.

마스크 필터에 익숙해지는 가장 좋은 방법은 이러한 정적 메서드를 사용 하 여 실험가 있습니다.The best way to become familiar with mask filters is by experimenting with these static methods. 전체 비트맵의 blur 마스크 필터를 사용할 수 있습니다.You can use a mask filter to blur an entire bitmap:

예제에서는 흐림Blur Example

또한이 문서를 만들고 드롭 그림자, 볼록 및 효과 조각에 대 한 이미지 필터를 사용 하 여 보여 줍니다.This article also demonstrates using an image filter to create a drop shadow, and for embossing and engraving effects.

벡터 그래픽 및 비트맵을 흐리게 표시Blurring vector graphics and bitmaps

만든 흐림 효과 SKImageFilter.CreateBlur 정적 메서드가에 흐리게 방법에 대 한 중요 한 장점 합니다 SKMaskFilter 클래스: 이미지 필터는 전체 비트맵을 흐리게 표시 수 있습니다.The blur effect created by the SKImageFilter.CreateBlur static method has a significant advantage over the blur methods in the SKMaskFilter class: The image filter can blur an entire bitmap. 메서드가 다음 구문:The method has the following syntax:

public static SkiaSharp.SKImageFilter CreateBlur (float sigmaX, float sigmaY,
                                                  SKImageFilter input = null,
                                                  SKImageFilter.CropRect cropRect = null);

이 메서드에 두 시그마 값 — 가로 방향 및 세로 방향에 대 한 두 번째 흐림 정도 대 한 첫 번째입니다.The method has two sigma values — the first for the blur extent in the horizontal direction and the second for the vertical direction. 세 번째 선택적 인수로 다른 이미지 필터를 지정 하 여 이미지 필터 연계할 수 있습니다.You can cascade image filters by specifying another image filter as the optional third argument. 자르기 사각형을 지정할 수도 있습니다.A cropping rectangle can also be specified.

이미지 실험 흐리게 표시 페이지에 SkiaSharpFormsDemos 포함 하는 두 Slider 흐림 효과의 다양 한 수준을 설정 시험해 볼 수 있는 뷰:The Image Blur Experiment page in the SkiaSharpFormsDemos includes two Slider views that let you experiment with setting various levels of blur:

<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.ImageBlurExperimentPage"
             Title="Image Blur Experiment">

    <StackLayout>
        <skia:SKCanvasView x:Name="canvasView"
                           VerticalOptions="FillAndExpand"
                           PaintSurface="OnCanvasViewPaintSurface" />

        <Slider x:Name="sigmaXSlider"
                Maximum="10"
                Margin="10, 0"
                ValueChanged="OnSliderValueChanged" />

        <Label Text="{Binding Source={x:Reference sigmaXSlider},
                              Path=Value,
                              StringFormat='Sigma X = {0:F1}'}"
               HorizontalTextAlignment="Center" />

        <Slider x:Name="sigmaYSlider"
                Maximum="10"
                Margin="10, 0"
                ValueChanged="OnSliderValueChanged" />

        <Label Text="{Binding Source={x:Reference sigmaYSlider},
                              Path=Value,
                              StringFormat='Sigma Y = {0:F1}'}"
               HorizontalTextAlignment="Center" />
    </StackLayout>
</ContentPage>

코드 숨김 파일에서는 두 개의 Slider 호출에 값 SKImageFilter.CreateBlur 에 대 한는 SKPaint 텍스트와 비트맵을 표시 하는 데 사용 되는 개체:The code-behind file uses the two Slider values to call SKImageFilter.CreateBlur for the SKPaint object used to display both text and a bitmap:

public partial class ImageBlurExperimentPage : ContentPage
{
    const string TEXT = "Blur My Text";

    SKBitmap bitmap = BitmapExtensions.LoadBitmapResource(
                            typeof(MaskBlurExperimentPage),
                            "SkiaSharpFormsDemos.Media.SeatedMonkey.jpg");

    public ImageBlurExperimentPage ()
    {
        InitializeComponent ();
    }

    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(SKColors.Pink);

        // Get values from sliders
        float sigmaX = (float)sigmaXSlider.Value;
        float sigmaY = (float)sigmaYSlider.Value;

        using (SKPaint paint = new SKPaint())
        {
            // Set SKPaint properties
            paint.TextSize = (info.Width - 100) / (TEXT.Length / 2);
            paint.ImageFilter = SKImageFilter.CreateBlur(sigmaX, sigmaY);

            // Get text bounds and calculate display rectangle
            SKRect textBounds = new SKRect();
            paint.MeasureText(TEXT, ref textBounds);
            SKRect textRect = new SKRect(0, 0, info.Width, textBounds.Height + 50);

            // Center the text in the display rectangle
            float xText = textRect.Width / 2 - textBounds.MidX;
            float yText = textRect.Height / 2 - textBounds.MidY;

            canvas.DrawText(TEXT, xText, yText, paint);

            // Calculate rectangle for bitmap
            SKRect bitmapRect = new SKRect(0, textRect.Bottom, info.Width, info.Height);
            bitmapRect.Inflate(-50, -50);

            canvas.DrawBitmap(bitmap, bitmapRect, BitmapStretch.Uniform, paint: paint);
        }
    }
}

스크린샷 세 개에 대 한 다양 한 설정을 표시 합니다 sigmaXsigmaY 설정:The three screenshots show various settings for the sigmaX and sigmaY settings:

흐린 실험 이미지Image Blur Experiment

흐리게 효과 다른 디스플레이 크기 및 해상도 간에 일관 된 설정 sigmaXsigmaY 흐리게 효과에 적용 되는 이미지의 렌더링 된 픽셀 크기에 비례 하는 값입니다.To keep the blur consistent among different display sizes and resolutions, set sigmaX and sigmaY to values that are proportional to the rendered pixel size of the image that the blur is applied to.

그림자Drop shadow

합니다 SKImageFilter.CreateDropShadow 정적 메서드를 만듭니다는 SKImageFilter 그림자에 대 한 개체:The SKImageFilter.CreateDropShadow static method creates an SKImageFilter object for a drop shadow:

public static SKImageFilter CreateDropShadow (float dx, float dy,
                                              float sigmaX, float sigmaY,
                                              SKColor color,
                                              SKDropShadowImageFilterShadowMode shadowMode,
                                              SKImageFilter input = null,
                                              SKImageFilter.CropRect cropRect = null);

이 개체를 설정 합니다 ImageFilter 의 속성을 SKPaint 개체 및 해당 개체를 사용 하 여 그리는 것 뒤에 그림자를 기준으로 해야 합니다.Set this object to the ImageFilter property of an SKPaint object, and anything you draw with that object will have a drop shadow behind it.

합니다 dxdy 매개 변수에서 그래픽 개체의 픽셀 단위의 그림자의 가로 및 세로 오프셋을 나타냅니다.The dx and dy parameters indicate the horizontal and vertical offsets of the shadow in pixels from the graphical object. 2 차원 그래픽에서 규칙 광원 이러한 두 인수가 모두 아래 및 그래픽 개체의 오른쪽에 그림자를 위치로 양의 되도록 하는 홈페이지에서 오는 것으로 가정 하는 것입니다.The convention in 2D graphics is to assume a light source coming from the upper left, which implies that both these arguments should be positive to position the shadow below and to the right of the graphical object.

합니다 sigmaXsigmaY 매개 변수 그림자에 대 한 요소를 흐리게 표시 됩니다.The sigmaX and sigmaY parameters are blurring factors for the drop shadow.

color 매개 변수는 그림자의 색입니다.The color parameter is the color of the drop shadow. SKColor 값 투명도 포함할 수 있습니다.This SKColor value can include transparency. 한 가지 방법은 색 값은 SKColors.Black.WithAlpha(0x80) 색 백그라운드 어두워집니다.One possibility is the color value SKColors.Black.WithAlpha(0x80) to darken any color background.

마지막 두 매개 변수는 선택적입니다.The final two parameters are optional.

합니다 섀도 실험 삭제 프로그램의 값을 시험해 볼 수 있습니다 dx, dysigmaX, 및 sigmaY 그림자 효과로 텍스트 문자열을 표시 하 합니다.The Drop Shadow Experiment program lets you experiment with values of dx, dy, sigmaX, and sigmaY to display a text string with a drop shadow. XAML 파일은 4 Slider 뷰 이러한 값을 설정 합니다.The XAML file instantiates four Slider views to set these values:

<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.DropShadowExperimentPage"
             Title="Drop Shadow Experiment">
    <ContentPage.Resources>
        <Style TargetType="Slider">
            <Setter Property="Margin" Value="10, 0" />
        </Style>

        <Style TargetType="Label">
            <Setter Property="HorizontalTextAlignment" Value="Center" />
        </Style>
    </ContentPage.Resources>

    <StackLayout>
        <skia:SKCanvasView x:Name="canvasView"
                           VerticalOptions="FillAndExpand"
                           PaintSurface="OnCanvasViewPaintSurface" />

        <Slider x:Name="dxSlider"
                Minimum="-20"
                Maximum="20"
                ValueChanged="OnSliderValueChanged" />

        <Label Text="{Binding Source={x:Reference dxSlider},
                              Path=Value,
                              StringFormat='Horizontal offset = {0:F1}'}" />

        <Slider x:Name="dySlider"
                Minimum="-20"
                Maximum="20"
                ValueChanged="OnSliderValueChanged" />

        <Label Text="{Binding Source={x:Reference dySlider},
                              Path=Value,
                              StringFormat='Vertical offset = {0:F1}'}" />

        <Slider x:Name="sigmaXSlider"
                Maximum="10"
                ValueChanged="OnSliderValueChanged" />

        <Label Text="{Binding Source={x:Reference sigmaXSlider},
                              Path=Value,
                              StringFormat='Sigma X = {0:F1}'}" />

        <Slider x:Name="sigmaYSlider"
                Maximum="10"
                ValueChanged="OnSliderValueChanged" />

        <Label Text="{Binding Source={x:Reference sigmaYSlider},
                              Path=Value,
                              StringFormat='Sigma Y = {0:F1}'}" />
    </StackLayout>
</ContentPage>

코드 숨김 파일을 파란색 텍스트 문자열에서 빨간색 그림자를 만들려면 해당 값을 사용 합니다.The code-behind file uses those values to create a red drop shadow on a blue text string:

public partial class DropShadowExperimentPage : ContentPage
{
    const string TEXT = "Drop Shadow";

    public DropShadowExperimentPage ()
    {
        InitializeComponent ();
    }

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

        // Get values from sliders
        float dx = (float)dxSlider.Value;
        float dy = (float)dySlider.Value;
        float sigmaX = (float)sigmaXSlider.Value;
        float sigmaY = (float)sigmaYSlider.Value;

        using (SKPaint paint = new SKPaint())
        {
            // Set SKPaint properties
            paint.TextSize = info.Width / 7;
            paint.Color = SKColors.Blue;
            paint.ImageFilter = SKImageFilter.CreateDropShadow(
                                    dx,
                                    dy,
                                    sigmaX,
                                    sigmaY,
                                    SKColors.Red,
                                    SKDropShadowImageFilterShadowMode.DrawShadowAndForeground);

            SKRect textBounds = new SKRect();
            paint.MeasureText(TEXT, ref textBounds);

            // Center the text in the display rectangle
            float xText = info.Width / 2 - textBounds.MidX;
            float yText = info.Height / 2 - textBounds.MidY;

            canvas.DrawText(TEXT, xText, yText, paint);
        }
    }
}

실행 중인 프로그램이 다음과 같습니다.Here's the program running:

섀도 실험을 삭제할Drop Shadow Experiment

맨 오른쪽에 있는 유니버설 Windows 플랫폼 스크린샷에 음수 오프셋된 값 발생할 그림자 위와 텍스트의 왼쪽에 표시 되도록 합니다.The negative offset values in the Universal Windows Platform screenshot at the far right cause the shadow to appear above and to the left of the text. 이 컴퓨터 그래픽에 대 한 규칙 아닌 오른쪽 아래에서 조명이 광원을 제안 합니다.This suggests a light source in the lower right, which is not the convention for computer graphics. 있지만 어떤 방식으로든에서 잘못 아마도 매우 흐린 만들어질 수도 되 그림자 이므로 대부분의 그림자 보다 더 장식용 것 같습니다.But it doesn't seem wrong in any way, perhaps because the shadow is also made very blurry and seems more ornamental than most drop shadows.

조명 효과Lighting Effects

SKImageFilter 클래스는 비슷한 이름 및 매개 변수, 복잡성을 증가 하는 순서에 나와 있는 6 개의 메서드를 정의 합니다.The SKImageFilter class defines six methods that have similar names and parameters, listed here in order of increasing complexity:

이러한 메서드는 3 차원 화면에서 광원의 다양 한 종류의 효과 모방 하는 이미지 필터를 만듭니다.These methods create image filters that mimic the effect of different kinds of light on three-dimensional surfaces. 결과 이미지 필터 서 이러한 개체를 상승 된 권한 또는 들어간 표시할 발생할 수 있습니다, 3D 공간에서 반사 강조 표시 또는 있었던 것 처럼 2 차원 개체를 나타냅니다.The resultant image filter illuminates two-dimensional objects as if they existed in 3D space, which can cause these objects to appear elevated or recessed, or with specular highlighting.

Distant 밝은 메서드 조명이 먼 거리에서를 가정 합니다.The Distant light methods assume that the light comes from a far distance. 불어넣을 개체를 목적으로 밝은 지구 작은 영역에서 Sun 마찬가지로 3D 공간에서 일관 된 단방향으로 간주 됩니다.For the purpose of illuminating objects, the light is assumed to point in one consistent direction in 3D space, much like the Sun on a small area of the Earth. Point 밝은 메서드를 내보내는 모든 방향으로 조명을 3D 공간에서 전구를 모방 합니다.The Point light methods mimic a light bulb positioned in 3D space that emits light in all directions. Spot light에 위치 및 방향 손전등 매우 유사 하 게 합니다.The Spot light has both a position and a direction, much like a flashlight.

위치 및 방향 3D 공간에서 둘 다의 값을 사용 하 여 지정 된를 SKPoint3 비슷한 구조 SKPoint 있지만 라는 세 가지 속성을 사용 하 여 XY, 및 Z합니다.Locations and directions in 3D space are both specified with values of the SKPoint3 structure, which is similar to SKPoint but with three properties named X, Y, and Z.

수와 이러한 메서드는 매개 변수는 복잡성으로 실험을 어려워집니다.The number and complexity of the parameters to these methods make experimentation with them difficult. 시작 하는 데는 먼 Light 실험 매개 변수를 실험해 볼 수 있습니다. 페이지를 CreateDistantLightDiffuse 메서드:To get you started, the Distant Light Experiment page lets you experiment with parameters to the CreateDistantLightDiffuse method:

public static SKImageFilter CreateDistantLitDiffuse (SKPoint3 direction,
                                                     SKColor lightColor,
                                                     float surfaceScale,
                                                     float kd,
                                                     SKImageFilter input = null,
                                                     SKImageFilter.CropRect cropRect = null);

페이지에는 마지막 두 개의 선택적 매개 변수를 사용 하지 않습니다.The page doesn't use the last two optional parameters.

Slider 는 XAML에서 뷰 파일 수를 선택 하면를 Z 의 좌표를 SKPoint3 값을 surfaceScale 매개 변수를 및 kd "확산 조명 상수"는 API 설명서에 정의 된 매개 변수:Three Slider views in the XAML file let you select the Z coordinate of the SKPoint3 value, the surfaceScale parameter, and the kd parameter, which is defined in the API documentation as the "diffuse lighting constant":

<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="SkiaLightExperiment.MainPage"
             Title="Distant Light Experiment">

    <StackLayout>

        <skia:SKCanvasView x:Name="canvasView"
                           PaintSurface="OnCanvasViewPaintSurface"
                           VerticalOptions="FillAndExpand" />

        <Slider x:Name="zSlider"
                Minimum="-10"
                Maximum="10"
                Margin="10, 0"
                ValueChanged="OnSliderValueChanged" />

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

        <Slider x:Name="surfaceScaleSlider"
                Minimum="-1"
                Maximum="1"
                Margin="10, 0"
                ValueChanged="OnSliderValueChanged" />

        <Label Text="{Binding Source={x:Reference surfaceScaleSlider},
                              Path=Value,
                              StringFormat='Surface Scale = {0:F1}'}"
               HorizontalTextAlignment="Center" />

        <Slider x:Name="lightConstantSlider"
                Minimum="-1"
                Maximum="1"
                Margin="10, 0"
                ValueChanged="OnSliderValueChanged" />

        <Label Text="{Binding Source={x:Reference lightConstantSlider},
                              Path=Value,
                              StringFormat='Light Constant = {0:F1}'}"
               HorizontalTextAlignment="Center" />
    </StackLayout>
</ContentPage>

코드 숨김 파일을 이러한 3 개의 값을 가져옵니다 및 사용 하 여 텍스트 문자열을 표시 하는 이미지 필터:The code-behind file obtains those three values and uses them to create an image filter to display a text string:

public partial class DistantLightExperimentPage : ContentPage
{
    const string TEXT = "Lighting";

    public DistantLightExperimentPage()
    {
        InitializeComponent();
    }

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

        float z = (float)zSlider.Value;
        float surfaceScale = (float)surfaceScaleSlider.Value;
        float lightConstant = (float)lightConstantSlider.Value;

        using (SKPaint paint = new SKPaint())
        {
            paint.IsAntialias = true;

            // Size text to 90% of canvas width
            paint.TextSize = 100;
            float textWidth = paint.MeasureText(TEXT);
            paint.TextSize *= 0.9f * info.Width / textWidth;

            // Find coordinates to center text
            SKRect textBounds = new SKRect();
            paint.MeasureText(TEXT, ref textBounds);

            float xText = info.Rect.MidX - textBounds.MidX;
            float yText = info.Rect.MidY - textBounds.MidY;

            // Create distant light image filter
            paint.ImageFilter = SKImageFilter.CreateDistantLitDiffuse(
                                    new SKPoint3(2, 3, z),
                                    SKColors.White,
                                    surfaceScale,
                                    lightConstant);

            canvas.DrawText(TEXT, xText, yText, paint);
        }
    }
}

첫 번째 인수 SKImageFilter.CreateDistantLitDiffuse 광원의 방향입니다.The first argument of SKImageFilter.CreateDistantLitDiffuse is the direction of the light. 양의 X 및 Y 좌표 광원 오른쪽 및 아래쪽 뾰족한 임을 나타냅니다.The positive X and Y coordinates indicate that the light is pointed to the right and down. 화면에 양수 Z 좌표 지점입니다.Positive Z coordinates point into the screen. XAML 파일을 사용 하면 음수 Z 값을 선택할 수 있습니다 하지만 볼 수 있도록에 작업이 수행 됩니다. 개념적으로 음의 Z 좌표는 화면 가리키도록 light을 발생 합니다.The XAML file allows you to select negative Z values, but that's only so you can see what happens: Conceptually, negative Z coordinates cause the light to point out of the screen. 항목에 대 한 다른 다음 작은 음수 값에 조명 효과 작동이 중지 됩니다.For anything other then small negative values, the lighting effect stops working.

surfaceScale 인수는-1에서 1까지 수 있습니다.The surfaceScale argument can range from –1 to 1. (높거나 낮은 값 있을 영향을 주지 않습니다.) 이들은 그래픽 개체 (이 경우 텍스트 문자열) 캔버스 화면에서 거리를 나타내는 Z 축에 상대 값입니다.(Higher or lower values have no further effect.) These are relative values in the Z axis that indicate the displacement of the graphical object (in this case, the text string) from the canvas surface. 캔버스의 화면 위의 텍스트 문자열을 발생 시키는 음수 및 양수 값을 캔버스에 들어온 사용 합니다.Use negative values to raise the text string above the surface of the canvas, and positive values to depress it into the canvas.

lightConstant 값은 양수 여야 합니다.The lightConstant value should be positive. (수 있는 프로그램을 음수 값 작업을 중지 하는 효과 입히기 볼 수 있도록 합니다.) 값이 높을수록 더 강 할수록 light을 발생합니다.(The program allows negative values so you can see that they cause the effect to stop working.) Higher values cause more intense light.

이러한 요소는 볼록 가져오려고 분산할 수 있습니다 하면 적용 surfaceScale (마찬가지로 iOS 및 Android 스크린샷) 음수인 및 음각을 하면 적용 surfaceScale 이 양수인 경우으로 오른쪽에서 UWP 스크린 샷 포함:These factors can be balanced to obtain an embossed effect when surfaceScale is negative (as with the iOS and Android screenshots) and an engraved effect when surfaceScale is positive, as with the UWP screenshot at the right:

멀리 떨어져 있는 밝은 실험Distant Light Experiment

Android 스크린 샷에 Z 값은 0으로, 아래쪽 및 오른쪽에 밝은 가리키고 있음을 의미 합니다.The Android screenshot has a Z value of 0, which means that the light is only pointing down and to the right. 백그라운드 켜지는 되지 않습니다 및 텍스트 문자열의 화면 켜지는 되지 중 하나입니다.The background isn't illuminated and the surface of the text string isn't illuminated either. 밝은 매우 미묘한 효과 텍스트의에 지만 영향을 줍니다.The light only effects the edge of the text for a very subtle effect.

다른 방법은 볼록 및 음각 텍스트 문서에서 설명 했습니다 The 변환 변환: 텍스트 문자열은 서로 약간 오프셋 되는 다양 한 색으로 두 번 표시 됩니다.An alternative approach to embossed and engraved text was demonstrated in the article The Translate Transform: The text string is displayed twice with different colors that are offset slightly from each other.