다음을 통해 공유


분리할 수 없는 혼합 모드

SkiaSharp 분리 가능한 혼합 모드 문서에서 본 것처럼 분리 가능한 혼합 모드는 빨간색, 녹색 및 파란색 채널에서 개별적으로 작업을 수행합니다. 분리할 수 없는 혼합 모드는 그렇지 않습니다. 색조, 채도 및 광도 수준의 색을 사용하여 분리할 수 없는 혼합 모드는 다음과 같은 흥미로운 방식으로 색을 변경할 수 있습니다.

분리할 수 없는 샘플

Hue-Saturation-Luminosity 모델

분리할 수 없는 혼합 모드를 이해하려면 대상 및 원본 픽셀을 Hue-Saturation-Luminosity 모델의 색으로 처리해야 합니다. 광도를 가벼움이라고도 합니다.

HSL 색 모델은 통합 Xamarin.Forms문서에서 설명했으며, 이 문서의 샘플 프로그램에서는 HSL 색을 실험할 수 있습니다. 정적 SKColor.FromHsl 메서드와 SKColor 함께 Hue, 채도 및 광도 값을 사용하여 값을 만들 수 있습니다.

색조는 색의 주요 파장입니다. 색조 값은 0에서 360까지의 범위이며 가산 및 빼기 주체를 순환합니다. 빨간색은 값 0, 노란색은 60, 녹색은 120, 시안은 180, 파란색은 240, 마젠타는 300이며 주기는 360에서 빨간색으로 돌아갑니다.

색이 흰색 또는 검은색 또는 회색 음영과 같이 주요 색이 없으면 Hue가 정의되지 않고 일반적으로 0으로 설정됩니다.

채도 값의 범위는 0에서 100까지이며 색의 순도를 나타냅니다. 채도 값 100은 가장 순수한 색이고 값이 100보다 낮으면 색이 더 회색으로 변합니다. 채도 값이 0이면 회색 음영이 발생합니다.

광도(또는 밝기) 값은 색의 밝기를 나타냅니다. 광도 값 0은 다른 설정에 관계없이 검은색입니다. 마찬가지로 광도 값 100은 흰색입니다.

HSL 값(0, 100, 50)은 순수 빨간색인 RGB 값(FF, 00, 00)입니다. HSL 값(180, 100, 50)은 RGB 값(00, FF, FF), 순수 시안입니다. 채도가 감소하면 주 색 구성 요소가 감소하고 다른 구성 요소가 증가합니다. 채도 수준이 0인 경우 모든 구성 요소는 동일하며 색은 회색 음영입니다. 검정으로 이동하려면 광도를 줄입니다. 가 흰색으로 이동하려면 광도를 높입니다.

혼합 모드 세부 정보

다른 혼합 모드와 마찬가지로 분리할 수 없는 4가지 혼합 모드에는 대상(비트맵 이미지인 경우가 많습니다)과 원본이 포함되며, 이는 종종 단일 색 또는 그라데이션입니다. 혼합 모드는 대상 및 원본의 Hue, 채도 및 광도 값을 결합합니다.

혼합 모드 원본의 구성 요소 대상의 구성 요소
Hue 색조 채도 및 광도
Saturation 채도 색조 및 광도
Color 색조 및 채도 광도
Luminosity 광도 색조 및 채도

알고리즘에 대한 W3C 작성 및 혼합 수준 1 사양을 참조하세요.

분리할 수 없는 혼합 모드 페이지에는 이러한 혼합 모드 중 하나와 HSL 색을 선택하는 세 Slider 가지 보기를 선택할 수 있는 항목이 포함되어 Picker 있습니다.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:skia="clr-namespace:SkiaSharp;assembly=SkiaSharp"
             xmlns:skiaviews="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms"
             x:Class="SkiaSharpFormsDemos.Effects.NonSeparableBlendModesPage"
             Title="Non-Separable Blend Modes">

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

        <Picker x:Name="blendModePicker"
                Title="Blend Mode"
                Margin="10, 0"
                SelectedIndexChanged="OnPickerSelectedIndexChanged">
            <Picker.ItemsSource>
                <x:Array Type="{x:Type skia:SKBlendMode}">
                    <x:Static Member="skia:SKBlendMode.Hue" />
                    <x:Static Member="skia:SKBlendMode.Saturation" />
                    <x:Static Member="skia:SKBlendMode.Color" />
                    <x:Static Member="skia:SKBlendMode.Luminosity" />
                </x:Array>
            </Picker.ItemsSource>

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

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

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

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

        <StackLayout Orientation="Horizontal">
            <Label x:Name="hslLabel"
                   HorizontalOptions="CenterAndExpand" />

            <Label x:Name="rgbLabel"
                   HorizontalOptions="CenterAndExpand" />

        </StackLayout>
    </StackLayout>
</ContentPage>

공간을 절약하기 위해 세 Slider 개의 보기는 프로그램의 사용자 인터페이스에서 식별되지 않습니다. 순서는 Hue, 채도 및 광도임을 기억해야 합니다. 페이지 아래쪽의 두 Label 보기에는 HSL 및 RGB 색 값이 표시됩니다.

코드 숨김 파일은 비트맵 리소스 중 하나를 로드하고 캔버스에 가능한 한 크게 표시한 다음 캔버스를 사각형으로 덮습니다. 사각형 색은 세 Slider 가지 뷰를 기반으로 하며 혼합 모드는 다음에서 Picker선택된 것입니다.

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

    public NonSeparableBlendModesPage()
    {
        InitializeComponent();
    }

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

    void OnSliderValueChanged(object sender, ValueChangedEventArgs e)
    {
        // Calculate new color based on sliders
        color = SKColor.FromHsl((float)hueSlider.Value,
                                (float)satSlider.Value,
                                (float)lumSlider.Value);

        // Use labels to display HSL and RGB color values
        color.ToHsl(out float hue, out float sat, out float lum);

        hslLabel.Text = String.Format("HSL = {0:F0} {1:F0} {2:F0}",
                                      hue, sat, lum);

        rgbLabel.Text = String.Format("RGB = {0:X2} {1:X2} {2:X2}",
                                      color.Red, color.Green, color.Blue);

        canvasView.InvalidateSurface();
    }

    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, BitmapStretch.Uniform);

        // Get blend mode from Picker
        SKBlendMode blendMode =
            (SKBlendMode)(blendModePicker.SelectedIndex == -1 ?
                                        0 : blendModePicker.SelectedItem);

        using (SKPaint paint = new SKPaint())
        {
            paint.Color = color;
            paint.BlendMode = blendMode;
            canvas.DrawRect(info.Rect, paint);
        }
    }
}

프로그램에서 세 개의 슬라이더에서 선택한 HSL 색 값을 표시하지 않습니다. 대신 해당 슬라이더에서 색 값을 만든 다음 메서드를 사용하여 ToHsl Hue, 채도 및 광도 값을 가져옵니다. 이 메서드는 FromHsl HSL 색을 구조체에 내부적으로 저장되는 RGB 색으로 변환하기 때문 SKColor 입니다. 메서드는 ToHsl RGB에서 HSL로 변환하지만 결과가 항상 원래 값이 되는 것은 아닙니다.

예를 들어 FromHsl HSL 값(180, 50, 0)을 RGB 색(0, 0, 0) Luminosity 으로 변환합니다. 이 메서드는 ToHsl 색조 및 채도 값이 관련이 없으므로 RGB 색(0, 0, 0)을 HSL 색(0, 0, 0)으로 변환합니다. 이 프로그램을 사용하는 경우 슬라이더로 지정한 색보다는 프로그램에서 사용하는 HSL 색의 표현을 확인하는 것이 좋습니다.

혼합 모드는 SKBlendModes.Hue 대상의 채도 및 광도 수준을 유지하면서 소스의 Hue 수준을 사용합니다. 이 혼합 모드를 테스트할 때 채도 및 광도 슬라이더는 0 또는 100이 아닌 다른 슬라이더로 설정해야 합니다. 이러한 경우 Hue가 고유하게 정의되지 않았기 때문입니다.

분리할 수 없는 혼합 모드 - Hue

왼쪽의 iOS 스크린샷과 마찬가지로 슬라이더를 0으로 설정하면 모든 항목이 빨간색으로 바뀝니다. 그러나 이미지가 완전히 녹색과 파란색이 없다는 것을 의미하지는 않습니다. 분명히 결과에는 여전히 회색 음영이 있습니다. 예를 들어 RGB 색(40, 40, C0)은 HSL 색(240, 50, 50)과 동일합니다. 색조는 파란색이지만 채도 값이 50이면 빨간색 및 녹색 구성 요소도 있음을 나타냅니다. Hue가 0으로 SKBlendModes.Hue설정된 경우 HSL 색은 RGB 색(C0, 40, 40)인 (0, 50, 50)입니다. 여전히 파란색과 녹색 구성 요소가 있지만 이제 주요 구성 요소는 빨간색입니다.

혼합 모드는 SKBlendModes.Saturation 원본의 채도 수준을 대상의 색조 및 광도와 결합합니다. 색조와 마찬가지로 광도가 0 또는 100이면 채도가 잘 정의되지 않습니다. 이론적으로, 이러한 두 극단 사이의 모든 광도 설정이 작동합니다. 그러나 광도 설정은 결과보다 더 많은 영향을 미치는 것 같습니다. 광도를 50으로 설정하면 그림의 채도 수준을 설정하는 방법을 확인할 수 있습니다.

분리할 수 없는 혼합 모드 - 채도

이 혼합 모드를 사용하여 둔한 이미지의 색 채도를 늘리거나 회색 음영으로 구성된 결과 이미지에 대해 채도를 0으로 줄일 수 있습니다(왼쪽의 iOS 스크린샷에서와 같이).

혼합 모드는 SKBlendModes.Color 대상의 광도를 유지하지만 원본의 색조와 채도를 사용합니다. 다시 말하지만, 이는 극단 사이의 어딘가에서 광도 슬라이더의 모든 설정이 작동해야 함을 의미합니다.

분리할 수 없는 혼합 모드 - 색

이 혼합 모드의 애플리케이션이 곧 표시됩니다.

마지막으로 혼합 SKBlendModes.Luminosity 모드는 .의 SKBlendModes.Color반대입니다. 대상의 색조와 채도를 유지하지만 원본의 광도를 사용합니다. Luminosity 혼합 모드는 일괄 처리에서 가장 신비합니다. 색조 및 채도 슬라이더는 이미지에 영향을 주지만 중간 광도에서도 이미지는 구별되지 않습니다.

분리할 수 없는 혼합 모드 - 광도

이론적으로 이미지의 광도를 늘리거나 줄이면 더 밝거나 어둡게 만들어야 합니다. 이 광도 속성 예제 또는 이 SKBlendMode 열거형 정의 에 관심이 있을 수 있습니다.

일반적으로 전체 대상 이미지에 적용된 단일 색으로 구성된 원본에서 분리할 수 없는 혼합 모드 중 하나를 사용하려는 경우가 아닙니다. 효과는 너무 큽다. 효과를 이미지의 한 부분으로 제한하려고 합니다. 이 경우 원본은 투명도를 통합하거나 원본이 더 작은 그래픽으로 제한될 수 있습니다.

분리 가능한 모드의 매트

다음은 샘플에 리소스로 포함된 비트맵 중 하나입니다. 파일 이름은 Banana.jpg.

바나나 원숭이

바나나만 포괄하는 매트를 만들 수 있습니다. 샘플의 리소스이기도 하다. 파일 이름은 BananaMatte.png.

바나나 매트

검은 바나나 모양 이외에도 비트맵의 나머지 부분도 투명합니다.

블루 바나나 페이지는 무광택을 사용하여 원숭이가 들고있는 바나나의 색조와 채도를 변경하지만 이미지에서 다른 것은 변경하지 않습니다.

다음 BlueBananaPage 클래스 에서 Banana.jpg 비트맵은 필드로 로드됩니다. 생성자는 BananaMatte.png 비트맵을 matteBitmap 개체로 로드하지만 생성자 이외의 개체는 유지하지 않습니다. 대신 명명 blueBananaBitmap 된 세 번째 비트맵이 만들어집니다. matteBitmap 그다음으로 그린 blueBananaBitmap 다음, 해당 집합이 SKPaint 파란색으로 Color 설정되고 해당 집합이 BlendMode .로 설정됩니다SKBlendMode.SrcIn. blueBananaBitmap 재기본 대부분 투명하지만 바나나의 단색 순수한 파란색 이미지와 함께 :

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

    SKBitmap blueBananaBitmap;

    public BlueBananaPage()
    {
        Title = "Blue Banana";

        // Load banana matte bitmap (black on transparent)
        SKBitmap matteBitmap = BitmapExtensions.LoadBitmapResource(
            typeof(BlueBananaPage),
            "SkiaSharpFormsDemos.Media.BananaMatte.png");

        // Create a bitmap with a solid blue banana and transparent otherwise
        blueBananaBitmap = new SKBitmap(matteBitmap.Width, matteBitmap.Height);

        using (SKCanvas canvas = new SKCanvas(blueBananaBitmap))
        {
            canvas.Clear();
            canvas.DrawBitmap(matteBitmap, new SKPoint(0, 0));

            using (SKPaint paint = new SKPaint())
            {
                paint.Color = SKColors.Blue;
                paint.BlendMode = SKBlendMode.SrcIn;
                canvas.DrawPaint(paint);
            }
        }

        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, BitmapStretch.Uniform);

        using (SKPaint paint = new SKPaint())
        {
            paint.BlendMode = SKBlendMode.Color;
            canvas.DrawBitmap(blueBananaBitmap,
                              info.Rect,
                              BitmapStretch.Uniform,
                              paint: paint);
        }
    }
}

PaintSurface 처리기는 바나나를 들고 원숭이와 비트맵을 그립니다. 이 코드 뒤에는 와 함께 SKBlendMode.Color표시됩니다blueBananaBitmap. 바나나 표면에서 각 픽셀의 색조와 채도는 240의 색조 값과 채도 값 100에 해당하는 단색 파란색으로 대체됩니다. 그러나 광도는 동일하게 기본, 이는 바나나가 새로운 색상에도 불구하고 현실적인 질감을 계속 유지한다는 것을 의미합니다.

블루 바나나

혼합 모드를 .로 변경해 SKBlendMode.Saturation보세요. 바나나는 노란색으로 기본 더 강렬한 노란색입니다. 실제 응용 프로그램에서는 바나나를 파랑으로 바꾸는 것보다 더 바람직한 효과일 수 있습니다.