Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Jak jste viděli v článku SkiaSharp Porter-Duff režimy směsi, režimy mixu Porter-Duff obecně provádějí operace výřezu. Samostatné režimy prolnutí se liší. Samostatné režimy mění jednotlivé červené, zelené a modré barevné komponenty obrázku. Oddělitelné režimy směsi mohou kombinovat barvu, aby ukázaly, že kombinace červené, zelené a modré je skutečně bílá:

Světlá a tmavá dvě způsoby
Je běžné mít rastrový obrázek, který je poněkud příliš tmavý nebo příliš světlý. Pokud chcete obrázek zesvětlit nebo ztmavit, můžete použít režimy oddělitelné kombinace. Ve skutečnosti jsou dva režimy oddělitelné kombinace ve výčtu SKBlendMode pojmenovány Lighten a Darken.
Tyto dva režimy jsou demonstrována na stránce Světlá a Tmavá . Soubor XAML vytvoří instanci dvou SKCanvasView objektů a dvou Slider zobrazení:
<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>
První SKCanvasView a Slider demonstruje SKBlendMode.Lighten druhý pár SKBlendMode.Darken. Slider Dvě zobrazení sdílejí stejnou obslužnou ValueChanged rutinu a dvě SKCanvasView sdílejí stejnou obslužnou PaintSurface rutinu. Oba obslužné rutiny událostí kontrolují, který objekt událost spouští:
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);
}
}
}
Obslužná rutina PaintSurface vypočítá obdélník vhodný pro rastrový obrázek. Obslužná rutina zobrazí tento rastrový obrázek a pak zobrazí obdélník nad bitmapou pomocí objektu SKPaint s jeho BlendMode vlastností nastavenou na SKBlendMode.Lighten nebo SKBlendMode.Darken. Vlastnost Color je šedý stín založený na objektu Slider. Lighten V režimu se barva pohybuje od černé po bílou, ale pro Darken režim, který se pohybuje od bílé po černou.
Snímky obrazovky zleva doprava zobrazují čím dál větší Slider hodnoty, protože horní obrázek je světlejší a dolní obrázek bude tmavší:
Tento program ukazuje normální způsob, jakým se používají oddělitelné režimy směsi: Cílem je obrázek určitého druhu, velmi často rastrový obrázek. Zdroj je obdélník zobrazený pomocí objektu SKPaint s jeho BlendMode vlastností nastavenou na oddělitelný režim blendu. Obdélník může být plná barva (jak je zde) nebo přechod. Průhlednost se obecně nepoužívá s oddělitelnými režimy prolnutí.
Při experimentování s tímto programem zjistíte, že tyto dva režimy směsi neosvětlí a ztmaví obrázek jednotně. Místo toho se zdá, Slider že je nastavená prahová hodnota určitého druhu. Když například zvětšíte Slider režim Lighten , tmavší oblasti obrázku se nejprve ztmavnou, zatímco světlejší oblasti zůstanou stejné.
Lighten Pokud je cílovým pixelem hodnota barvy RGB (Dr, Dg, Db) a zdrojový pixel je barva (Sr, Sg, Sb), pak výstup je (Or, Og, Ob) vypočítán takto:
Or = max(Dr, Sr)
Og = max(Dg, Sg)
Ob = max(Db, Sb)
Pro červenou, zelenou a modrou zvlášť je výsledkem větší cíl a zdroj. To vytváří efekt zsvětlování tmavých oblastí cíle jako první.
Režim Darken je podobný s tím rozdílem, že výsledek je menší než cíl a zdroj:
Or = min(Dr, Sr)
Og = min(Dg, Sg)
Ob = min(Db, Sb)
Červené, zelené a modré komponenty jsou zpracovávány samostatně, což je důvod, proč se tyto režimy mixu označují jako oddělené režimy blendu. Z tohoto důvodu lze zkratky DC a Sc použít pro cílové a zdrojové barvy a je zřejmé, že výpočty platí pro každou červenou, zelenou a modrou komponentu samostatně.
V následující tabulce jsou uvedeny všechny režimy oddělených kombinací se stručným vysvětlením toho, co dělají. Druhý sloupec zobrazuje zdrojovou barvu, která nevyvolá žádnou změnu:
| Režim blendu | Beze změny | Operace |
|---|---|---|
Plus |
Černá | Zlehčí přidáním barev: Sc + Dc |
Modulate |
Bílá | Ztmavne se vynásobením barev: Sc· Dc |
Screen |
Černá | Doplňuje součin doplňků: Sc + Dc – Sc· Dc |
Overlay |
Šedá | Inverzní funkce HardLight |
Darken |
Bílá | Minimum barev: min(Sc, Dc) |
Lighten |
Černá | Maximum barev: max(Sc, Dc) |
ColorDodge |
Černá | Brightens destination based on source |
ColorBurn |
Bílá | Ztmavne cíl na základě zdroje. |
HardLight |
Šedá | Podobá se efektu drsného spotlightu |
SoftLight |
Šedá | Podobá se efektu měkkého spotlightu |
Difference |
Černá | Odečte tmavší od světlejšího: Abs(Dc – Sc) |
Exclusion |
Černá | Podobá se nižšímu Difference kontrastu |
Multiply |
Bílá | Ztmavne se vynásobením barev: Sc· Dc |
Podrobnější algoritmy najdete ve specifikaci W3C Compositing a Blending Level 1 a Skia SkBlendMode Reference, i když notace v těchto dvou zdrojích není stejná. Mějte na paměti, že Plus se běžně považuje za režim směsi Porter-Duff a Modulate není součástí specifikace W3C.
Pokud je zdroj průhledný, pak pro všechny oddělitelné režimy blendu s výjimkou Modulate, režim blendu nemá žádný vliv. Jak jste viděli dříve, Modulate režim blendu zahrnuje alfa kanál do násobení. Modulate V opačném případě má stejný účinek jako Multiply.
Všimněte si dvou pojmenovaných ColorDodge režimů a ColorBurn. Slova dodge a burn vznikly v fotografických tmavých praktikách. Zvětšovací zvětšovač vytváří fotografickou tisk tak, že svítí světlo zápornou. Bez světla je tisk bílý. Tisk je tmavší, protože na tisk po delší dobu spadne více světla. Tvůrci tisku často použili rukou nebo malý objekt k blokování toho, aby některé světlo připadalo na určitou část tisku, čímž je tato oblast světlejší. To se označuje jako odškrtnutí. Naopak neprůsvitný materiál s otvorem v něm (nebo rukou blokující většinu světla) lze použít k nasměrování více světla na konkrétním místě, aby se ztmavlo, označované jako hořící.
Program Dodge a Burn je velmi podobný Lighten a Darken. Soubor XAML je strukturovaný stejně, ale s různými názvy prvků a soubor s kódem je podobně podobný, ale účinek těchto dvou režimů blendu je poměrně odlišný:
U malých Slider hodnot Lighten režim nejprve zsvětlí tmavé oblasti, zatímco ColorDodge se rovnoměrněji zsvětlí.
Programy aplikací pro zpracování obrázků často umožňují omezit odstraňování a vypalování na určité oblasti, stejně jako v tmavé místnosti. Toho lze dosáhnout přechody nebo rastrovým obrázkem s různými odstíny šedé.
Prozkoumání oddělených režimů prolnutí
Stránka Separable Blend Modes umožňuje prozkoumat všechny samostatné režimy blendu. Zobrazí cíl rastrového obrázku a barevný zdroj obdélníku pomocí jednoho z režimů prolnutí.
Soubor XAML definuje Picker (pro výběr režimu mixu) a čtyři posuvníky. První tři posuvníky umožňují nastavit červené, zelené a modré komponenty zdroje. Čtvrtý posuvník má tyto hodnoty přepsat nastavením šedého odstínu. Jednotlivé posuvníky nejsou identifikovány, ale barvy označují jejich funkci:
<?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>
Soubor s kódem načte jeden z rastrových prostředků a nakreslí ho dvakrát, jednou v horní polovině plátna a znovu v dolní polovině plátna:
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);
}
}
}
V dolní části PaintSurface obslužné rutiny se nakreslený obdélník přes druhý rastrový obrázek s vybraným režimem blendu a vybranou barvou. Upravený rastrový obrázek můžete porovnat v dolní části s původním rastrovým obrázkem nahoře:
Doplňkové a subtractive primární barvy
Stránka Primární barvy nakreslí tři překrývající se kruhy červené, zelené a modré:
Jedná se o doplňkové primární barvy. Kombinace všech dvou vytváří azurovou, purpurovou a žlutou a kombinaci všech tří je bílá.
Tyto tři kruhy jsou kresleny s režimem SKBlendMode.Plus , ale můžete také použít Screen, Lightennebo Difference pro stejný efekt. Tady je 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);
}
}
}
}
Program obsahuje .TabGestureRecognizer Když klepnete nebo kliknete na obrazovku, program použije SKBlendMode.Multiply k zobrazení tří dílčích primárních primár:
Režim Darken funguje také pro tento stejný efekt.




