Режимы отделяемых blendThe separable blend modes

Загрузить образец загрузить примерDownload Sample Download the sample

Как было показано в этой статье режимы смешения SkiaSharp Портер-Duff, режимов смешения Портер Duff обычно выполняют операции обрезки.As you saw in the article SkiaSharp Porter-Duff blend modes, the Porter-Duff blend modes generally perform clipping operations. Режимы отделяемых blend различаются.The separable blend modes are different. Режимы отделяемых alter компонентов отдельных красного, зеленого и синего цвета изображения.The separable modes alter the individual red, green, and blue color components of an image. Режимы отделяемых blend можно смешивать цвета, чтобы продемонстрировать, что сочетание красного, зеленого и синего действительно белый:Separable blend modes can mix color to demonstrate that the combination of red, green, and blue is indeed white:

Основных цветовPrimary Colors

Осветление и темнее два способаLighten and darken two ways

Это часто используются Битовая карта, немного слишком темная или слишком света.It is common to have a bitmap that is somewhat too dark or too light. Можно использовать режимы отделяемых наложения светлее или темнее imabe.You can use separable blend modes to lighten or darken the imabe. Действительно, два из режимы отделяемых blend SKBlendMode перечисления называются Lighten и Darken.Indeed, two of the separable blend modes in the SKBlendMode enumeration are named Lighten and Darken.

В этих двух режимов демонстрируются «Замена светлым» и «замена темным» страницы.These two modes are demonstrated in the Lighten and Darken page. Файл XAML создает два SKCanvasView объектов и два Slider представления:The XAML file instantiates two SKCanvasView objects and two Slider views:

<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.LightenAndDarkenPage"
             Title="Lighten and Darken">
    <StackLayout>
        <skia:SKCanvasView x:Name="lightenCanvasView"
                           VerticalOptions="FillAndExpand"
                           PaintSurface="OnCanvasViewPaintSurface" />

        <Slider x:Name="lightenSlider"
                Margin="10"
                ValueChanged="OnSliderValueChanged" />

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

        <Slider x:Name="darkenSlider"
                Margin="10"
                ValueChanged="OnSliderValueChanged" />
    </StackLayout>
</ContentPage>

Первый SKCanvasView и Slider демонстрации SKBlendMode.Lighten и демонстрирует, Вторая пара SKBlendMode.Darken.The first SKCanvasView and Slider demonstrate SKBlendMode.Lighten and the second pair demonstrates SKBlendMode.Darken. Два Slider представления одного и того же ValueChanged обработчик, а два SKCanvasView одного и того же PaintSurface обработчика.The two Slider views share the same ValueChanged handler, and the two SKCanvasView share the same PaintSurface handler. Оба проверка обработчики событий, какой он генерирует события:Both event handlers check which object is firing the event:

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

    public LightenAndDarkenPage ()
    {
        InitializeComponent ();
    }

    void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
    {
        if ((Slider)sender == lightenSlider)
        {
            lightenCanvasView.InvalidateSurface();
        }
        else
        {
            darkenCanvasView.InvalidateSurface();
        }
    }

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

        canvas.Clear();

        // Find largest size rectangle in canvas
        float scale = Math.Min((float)info.Width / bitmap.Width,
                               (float)info.Height / bitmap.Height);
        SKRect rect = SKRect.Create(scale * bitmap.Width, scale * bitmap.Height);
        float x = (info.Width - rect.Width) / 2;
        float y = (info.Height - rect.Height) / 2;
        rect.Offset(x, y);

        // Display bitmap
        canvas.DrawBitmap(bitmap, rect);

        // Display gray rectangle with blend mode
        using (SKPaint paint = new SKPaint())
        {
            if ((SKCanvasView)sender == lightenCanvasView)
            {
                byte value = (byte)(255 * lightenSlider.Value);
                paint.Color = new SKColor(value, value, value);
                paint.BlendMode = SKBlendMode.Lighten;
            }
            else
            {
                byte value = (byte)(255 * (1 - darkenSlider.Value));
                paint.Color = new SKColor(value, value, value);
                paint.BlendMode = SKBlendMode.Darken;
            }

            canvas.DrawRect(rect, paint);
        }
    }
}

PaintSurface Обработчик вычисляет прямоугольника, подходящий для растрового изображения.The PaintSurface handler calculates a rectangle suitable for the bitmap. Обработчик, отображает этот точечный рисунок, а затем отображает прямоугольник растрового изображения, используя SKPaint объект с его BlendMode свойство значение SKBlendMode.Lighten или SKBlendMode.Darken.The handler displays that bitmap and then displays a rectangle over the bitmap using an SKPaint object with its BlendMode property set to SKBlendMode.Lighten or SKBlendMode.Darken. Color Свойство является оттенком серого, на основе Slider.The Color property is a gray shade based on the Slider. Для Lighten режим, цветовые диапазоны от черного к белому, но для Darken его диапазон от белого к черному режим.For the Lighten mode, the color ranges from black to white, but for the Darken mode it ranges from white to black.

Снимки экрана в направлении слева направо Показать все большей Slider значений по верхнему изображению получает светлее и нижнее изображение получает темнее:The screenshots from left to right show increasingly larger Slider values as the top image gets lighter and the bottom image gets darker:

Осветление и который затемняетсяLighten and Darken

В этой программе демонстрируется обычным способом, в котором используются режимы отделяемых наложения: Назначения — это образ какого-либо рода, очень часто растрового изображения.This program demonstrates the normal way in which the separable blend modes are used: The destination is an image of some sort, very often a bitmap. Источник представляет собой прямоугольник, отображается с помощью SKPaint объект с его BlendMode свойства задан режим отделяемых blend.The source is a rectangle displayed using an SKPaint object with its BlendMode property set to a separable blend mode. Прямоугольник может быть сплошным цветом (как показано ниже) или градиент.The rectangle can be a solid color (as it is here) or a gradient. Прозрачность — не обычно используется с режимами отделяемых blend.Transparency is not generally used with the separable blend modes.

Во время экспериментов с этой программой, вы обнаружите, что эти два blend не светлее и изображение единообразно.As you experiment with this program, you'll discover that these two blend modes do not lighten and darken the image uniformly. Вместо этого Slider кажется Установите пороговое значение какого-либо рода.Instead, the Slider seems to set a threshold of some sort. Например, с увеличением Slider для Lighten режим, более темные области изображения произойти свет сначала светлые области не изменяются.For example, as you increase the Slider for the Lighten mode, the darker areas of the image get light first while the lighter areas remain the same.

Для Lighten режим, если конечная точка является значение цвета RGB (БД для аварийного восстановления, группе рассылки,), а пикселей источника является цветом (Sr Sg, Sb), а затем выходные данные (или Og Ob) вычисляется следующим образом:For the Lighten mode, if the destination pixel is the RGB color value (Dr, Dg, Db), and the source pixel is the color (Sr, Sg, Sb), then the output is (Or, Og, Ob) calculated as follows:

Or = max(Dr, Sr) Og = max(Dg, Sg)Or = max(Dr, Sr) Og = max(Dg, Sg) Ob = max(Db, Sb)

Для красного, зеленого и синего отдельно, результатом является более источника и назначения.For red, green, and blue separately, the result is the greater of the destination and source. Этот сценарий создает эффект сначала Осветление темные области назначения.This produces the effect of lightening the dark areas of the destination first.

Darken Режим похож, за исключением того, что результат, равно меньшему из источника и назначения:The Darken mode is similar except that the result is the lesser of the destination and source:

Or = min(Dr, Sr) Og = min(Dg, Sg)Or = min(Dr, Sr) Og = min(Dg, Sg) Ob = min(Db, Sb)

Красного, зеленого и синего компонентов, каждый обрабатываются отдельно, поэтому эти режимы смешения, называются отделяемых режимы смешения.The red, green, and blue components are each handled separately, which is why these blend modes are referred to as the separable blend modes. По этой причине аббревиатур Dc и Sc может использоваться для назначения и исходного цвета и понятно, что вычисления применить к каждому из красного, зеленого и синего компонентов отдельно.For this reason, the abbreviations Dc and Sc can be used for the destination and source colors, and it's understood that calculations apply to each of the red, green, and blue components separately.

Ниже приведены все режимы отделяемых наложения с краткий перечень их предназначение.The following table shows all the separable blend modes with brief explanations of what they do. Во втором — исходного цвета, никаких изменений не происходит:The second column shows the source color that produces no change:

Режим наложенияBlend Mode Без измененийNo change ОперацияOperation
Plus ЧерныйBlack Осветляет, добавив цвета: SC + контроллера доменаLightens by adding colors: Sc + Dc
Modulate БелыйWhite Затемняет путем умножения цвета: SC· Контроллер доменаDarkens by multiplying colors: Sc·Dc
Screen ЧерныйBlack Дополняет произведение дополняет: SC + Dc – Sc· Контроллер доменаComplements product of complements: Sc + Dc – Sc·Dc
Overlay СерыйGray Обратное значение HardLightInverse of HardLight
Darken БелыйWhite Минимальное цветов: min (Sc, контроллер домена)Minimum of colors: min(Sc, Dc)
Lighten ЧерныйBlack Максимальное число цветов: max (Sc, контроллер домена)Maximum of colors: max(Sc, Dc)
ColorDodge ЧерныйBlack Черным назначения на основе источникаBrightens destination based on source
ColorBurn БелыйWhite Затемняет назначения на основе источникаDarkens destination based on source
HardLight СерыйGray Аналогичную последствия Харша spotlightSimilar to effect of harsh spotlight
SoftLight СерыйGray Аналогичную последствия Мягкий прожекторSimilar to effect of soft spotlight
Difference ЧерныйBlack Вычитает темнее из более светлой: ABS (Dc – Sc)Subtracts the darker from the lighter: Abs(Dc – Sc)
Exclusion ЧерныйBlack Аналогичную Difference но понизить контрастностиSimilar to Difference but lower contrast
Multiply БелыйWhite Затемняет путем умножения цвета: SC· Контроллер доменаDarkens by multiplying colors: Sc·Dc

Более подробные алгоритмы можно найти в W3C композиции и наложения уровня 1 спецификации и Skia ссылку SkBlendMode , несмотря на то, что нотация в этих двух источников, не совпадает.More detailed algorithms can be found in the W3C Compositing and Blending Level 1 specification and the Skia SkBlendMode Reference, although the notation in these two sources is not the same. Имейте в виду, что Plus часто рассматривается как режим наложения Duff Портер, и Modulate не является частью спецификации W3C.Keep in mind that Plus is commonly regarded as a Porter-Duff blend mode, and Modulate is not part of the W3C specification.

Если источником является прозрачным, затем для всех разделяемых режимы смешения за исключением Modulate, режим наложения не оказывает влияния.If the source is transparent, then for all the separable blend modes except Modulate, the blend mode has no effect. Как вы видели ранее, Modulate режим blend включает в себя альфа-канал в умножения.As you've seen earlier, the Modulate blend mode incorporates the alpha channel in the multiplication. В противном случае Modulate имеет тот же эффект, что Multiply.Otherwise, Modulate has the same effect as Multiply.

Обратите внимание, что два режима с именем ColorDodge и ColorBurn.Notice the two modes named ColorDodge and ColorBurn. Слова избавиться от и записать была создана в фотографический фотолаборатория методики.The words dodge and burn originated in photographic darkroom practices. Лупа делает фотографический печати, проливая свет через отрицательное.An enlarger makes a photographic print by shining light through a negative. С помощью отсутствии света печати будет белым.With no light, the print is white. Печать получает более темный оттенок, так как дополнительные свет ложится на печать для более длительного периода времени.The print gets darker as more light falls on the print for a longer period of time. Печать принимающих часто используется для блокировки некоторых света попала в определенной части печати, что делает более светлые области вручную или маленьких объектов.Print-makers often used a hand or small object to block some of the light from falling on a certain part of the print, making that area lighter. Этот процесс называется Осветление.This is known as dodging. И наоборот, Непрозрачный материал отверстия в ее (или блокировки большую часть света руки) может использоваться для направления дополнительные свет в определенной точке на который затемняется, он вызывается записи.Conversely, opaque material with a hole in it (or hands blocking most of the light) could be used to direct more light in a particular spot to darken it, called burning.

Избавиться от и Burn программой очень похожа на «Замена светлым» и «замена темным».The Dodge and Burn program is very similar to Lighten and Darken. Файл XAML является структурированные прежним, но с именами различных элементов и файл с выделенным кодом довольно аналогично, но последствия этих режимов два blend отличается:The XAML file is structured the same but with different element names, and the code-behind file is likewise quite similar, but the effect of these two blend modes is quite different:

Избавиться от и BurnDodge and Burn

Для небольших Slider значения, Lighten режим осветляет "темных" областях во-первых, хотя ColorDodge осветляет более равномерно.For small Slider values, the Lighten mode lightens dark areas first, while ColorDodge lightens more uniformly.

Обработка изображений приложения часто позволяют Осветление и быть доступны только для конкретной области, так же, как в фотолаборатория записи.Image-processing application programs often allow dodging and burning to be restricted to specific areas, just like in a darkroom. Это можно сделать, градиентов или растрового изображения с помощью различных оттенков серого.This can be accomplished by gradients, or by a bitmap with varying shades of gray.

Изучение режимы отделяемых blendExploring the separable blend modes

Разделяемых режимах Blend страница позволяет изучить все режимы отделяемых blend.The Separable Blend Modes page allows you to examine all the separable blend modes. Он отображает точечный рисунок назначения и источником цветным прямоугольником, используя один из режимов смешения.It displays a bitmap destination and a colored rectangle source using one of the blend modes.

В файле XAML определяется Picker (чтобы выбрать режим наложения) и четыре ползунка.The XAML file defines a Picker (to select the blend mode) and four sliders. Первые три ползунков можно будет задать красного, зеленого и синего компонентов источника.The first three sliders let you set the red, green, and blue components of the source. Четвертый ползунок должен переопределить эти значения, задав оттенком серого.The fourth slider is intended to override those values by setting a gray shade. Отдельные ползунки не определены, но цвета обозначают их функции:The individual sliders are not identified, but colors indicate their function:

<?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:skia="clr-namespace:SkiaSharp;assembly=SkiaSharp"
             xmlns:skiaviews="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms"
             x:Class="SkiaSharpFormsDemos.Effects.SeparableBlendModesPage"
             Title="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.Plus" />
                    <x:Static Member="skia:SKBlendMode.Modulate" />
                    <x:Static Member="skia:SKBlendMode.Screen" />
                    <x:Static Member="skia:SKBlendMode.Overlay" />
                    <x:Static Member="skia:SKBlendMode.Darken" />
                    <x:Static Member="skia:SKBlendMode.Lighten" />
                    <x:Static Member="skia:SKBlendMode.ColorDodge" />
                    <x:Static Member="skia:SKBlendMode.ColorBurn" />
                    <x:Static Member="skia:SKBlendMode.HardLight" />
                    <x:Static Member="skia:SKBlendMode.SoftLight" />
                    <x:Static Member="skia:SKBlendMode.Difference" />
                    <x:Static Member="skia:SKBlendMode.Exclusion" />
                    <x:Static Member="skia:SKBlendMode.Multiply" />
                </x:Array>
            </Picker.ItemsSource>

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

        <Slider x:Name="redSlider"
                MinimumTrackColor="Red"
                MaximumTrackColor="Red"
                Margin="10, 0"
                ValueChanged="OnSliderValueChanged" />

        <Slider x:Name="greenSlider"
                MinimumTrackColor="Green"
                MaximumTrackColor="Green"
                Margin="10, 0"
                ValueChanged="OnSliderValueChanged" />

        <Slider x:Name="blueSlider"
                MinimumTrackColor="Blue"
                MaximumTrackColor="Blue"
                Margin="10, 0"
                ValueChanged="OnSliderValueChanged" />

        <Slider x:Name="graySlider"
                MinimumTrackColor="Gray"
                MaximumTrackColor="Gray"
                Margin="10, 0"
                ValueChanged="OnSliderValueChanged" />

        <Label x:Name="colorLabel"
               HorizontalTextAlignment="Center" />

    </StackLayout>
</ContentPage>

Файл с выделенным кодом загружает один из ресурсов точечного рисунка и отображает его дважды, один раз в верхней половине холста, а затем снова в нижней половине холста:The code-behind file loads one of the bitmap resources and draws it twice, once in the top half of the canvas and again in the bottom half of the canvas:

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

    public SeparableBlendModesPage()
    {
        InitializeComponent();
    }

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

    void OnSliderValueChanged(object sender, ValueChangedEventArgs e)
    {
        if (sender == graySlider)
        {
            redSlider.Value = greenSlider.Value = blueSlider.Value = graySlider.Value;
        }

        colorLabel.Text = String.Format("Color = {0:X2} {1:X2} {2:X2}",
                                        (byte)(255 * redSlider.Value),
                                        (byte)(255 * greenSlider.Value),
                                        (byte)(255 * blueSlider.Value));

        canvasView.InvalidateSurface();
    }

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

        canvas.Clear();

        // Draw bitmap in top half
        SKRect rect = new SKRect(0, 0, info.Width, info.Height / 2);
        canvas.DrawBitmap(bitmap, rect, BitmapStretch.Uniform);

        // Draw bitmap in bottom halr
        rect = new SKRect(0, info.Height / 2, info.Width, info.Height);
        canvas.DrawBitmap(bitmap, rect, BitmapStretch.Uniform);

        // Get values from XAML controls
        SKBlendMode blendMode =
            (SKBlendMode)(blendModePicker.SelectedIndex == -1 ?
                                        0 : blendModePicker.SelectedItem);

        SKColor color = new SKColor((byte)(255 * redSlider.Value),
                                    (byte)(255 * greenSlider.Value),
                                    (byte)(255 * blueSlider.Value));

        // Draw rectangle with blend mode in bottom half
        using (SKPaint paint = new SKPaint())
        {
            paint.Color = color;
            paint.BlendMode = blendMode;
            canvas.DrawRect(rect, paint);
        }
    }
}

В конце PaintSurface обработчик, прямоугольника рисуется через второй растровое изображение с режим выбранного наложения и выбранного цвета.Towards the bottom of the PaintSurface handler, a rectangle is drawn over the second bitmap with the selected blend mode and the selected color. Вы можете сравнить измененный растрового изображения в нижней исходное растровое изображение в верхней:You can compare the modified bitmap at the bottom with the original bitmap at the top:

Режимы отделяемых наложенияSeparable Blend Modes

Сложения и вычитания основных цветовAdditive and subtractive primary colors

Основных цветов страницы Рисует три круга красный, зеленый и синий:The Primary Colors page draws three overlapping circles of red, green, and blue:

Аддитивные основных цветовAdditive Primary Colors

Они являются аддитивными основных цветов.These are the additive primary colors. Создавать сочетания любыми двумя голубой, пурпурный и желтый и сочетание всех трех белый.Combinations of any two produce cyan, magenta, and yellow, and a combination of all three is white.

Эти три круга рисуются с SKBlendMode.Plus режим, но можно также использовать Screen, Lighten, или Difference для тот же эффект.These three circles are drawn with the SKBlendMode.Plus mode, but you can also use Screen, Lighten, or Difference for the same effect. Вот программы:Here's the program:

public class PrimaryColorsPage : ContentPage
{
    bool isSubtractive;

    public PrimaryColorsPage ()
    {
        Title = "Primary Colors";

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

        // Switch between additive and subtractive primaries at tap
        TapGestureRecognizer tap = new TapGestureRecognizer();
        tap.Tapped += (sender, args) =>
        {
            isSubtractive ^= true;
            canvasView.InvalidateSurface();
        };
        canvasView.GestureRecognizers.Add(tap);

        Content = canvasView;
    }

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

        canvas.Clear();

        SKPoint center = new SKPoint(info.Rect.MidX, info.Rect.MidY);
        float radius = Math.Min(info.Width, info.Height) / 4;
        float distance = 0.8f * radius;     // from canvas center to circle center
        SKPoint center1 = center + 
            new SKPoint(distance * (float)Math.Cos(9 * Math.PI / 6),
                        distance * (float)Math.Sin(9 * Math.PI / 6));
        SKPoint center2 = center +
            new SKPoint(distance * (float)Math.Cos(1 * Math.PI / 6),
                        distance * (float)Math.Sin(1 * Math.PI / 6));
        SKPoint center3 = center +
            new SKPoint(distance * (float)Math.Cos(5 * Math.PI / 6),
                        distance * (float)Math.Sin(5 * Math.PI / 6));

        using (SKPaint paint = new SKPaint())
        {
            if (!isSubtractive)
            {
                paint.BlendMode = SKBlendMode.Plus; 
                System.Diagnostics.Debug.WriteLine(paint.BlendMode);

                paint.Color = SKColors.Red;
                canvas.DrawCircle(center1, radius, paint);

                paint.Color = SKColors.Lime;    // == (00, FF, 00)
                canvas.DrawCircle(center2, radius, paint);

                paint.Color = SKColors.Blue;
                canvas.DrawCircle(center3, radius, paint);
            }
            else
            {
                paint.BlendMode = SKBlendMode.Multiply
                System.Diagnostics.Debug.WriteLine(paint.BlendMode);

                paint.Color = SKColors.Cyan;
                canvas.DrawCircle(center1, radius, paint);

                paint.Color = SKColors.Magenta;
                canvas.DrawCircle(center2, radius, paint);

                paint.Color = SKColors.Yellow;
                canvas.DrawCircle(center3, radius, paint);
            }
        }
    }
}

Программа содержит TabGestureRecognizer.The program includes a TabGestureRecognizer. Если вы коснитесь или щелкните экран, программа использует SKBlendMode.Multiply для отображения три первичные реплики для вычитания:When you tap or click the screen, the program uses SKBlendMode.Multiply to display the three subtractive primaries:

Субтрактивным основных цветовSubtractive Primary Colors

Darken Режим также подходит для этого же эффекта.The Darken mode also works for this same effect.