Java týden První novoroční výprodej
Hledáš brigádu v IT, která bude 100 % home office a 100 % flexibilní? Pak napiš na: redakce [zavináč] itnetwork.cz pro více info!
80 % bodů zdarma díky akci Black Friday! Tento týden rovněž sleva na e-learning Java až 80 %

Vektorová grafika v C# .NET WPF - Úvod

Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem.
Vydávání, hosting a aktualizace umožňují jeho sponzoři.

V dnešní lekci si popíšeme co je to vektorová grafika a jak se liší oproti grafice rastrové. Dále si ukážeme, jak se k této problematice staví .NET framework a WPF. Poté si zkusíme přes XAML nakreslit pár jednoduchých objektů.

Vektorová vs. rastrová grafika

Velmi laicky můžeme říci, že vektorový obrázek si můžeme zvětšit jak chceme a nikdy se nám nerozmaže nebo nerozpixeluje. To je velmi lákavé, protože takový obrázek je plně responzivní a stále 100% ostrý, navíc zabírá velmi málo paměti a naše aplikace pak vypadá na všech zařízeních stejně hezky. Není divu, že např. SVG ikony jsou dnes na webu velmi populární. A i my budeme vektorové ikony ve svých WPF aplikacích preferovat.

Vektorový obrázek

Obrázek v sobě obsahuje matematický zápis souřadnic bodů (vrcholů) a jejich spojnic (hran), který vytváří požadovaný obrazec (např. trojúhelník, kruh, čtverec...). Kombinováním a prolínáním těchto obrazců se poté vytvářejí obrazce složitější. Dále se ve vektorových obrázcích specifikují informace jako tloušťka čáry, barva výplně atd. Z toho vyplývá, že s jakýmkoliv zvětšením či zmenšením obrazce se mění jen poměr vzdáleností mezi vrcholy.

Rasterizace

A jak se křivky vykreslí? To, co poté vidíme na obrazovce, se musí samozřejmě znovu "rasterizovat", neboli vykreslit na 2D ploše našeho monitoru:

mřížka znázorňuje zobrazitelné pixely, trojúhelník vektorovou grafiku, a zelená barva vykreslený trojúhelník

Jak sami vidíte, vykreslení vektorového obrázku na obrazovku vytváří při malém počtu pixelů "schody" neboli aliasing. WPF za nás však použije pokročilejší algoritmy, tzv. anti-aliasing, aby byly jednotlivé křivky obrázku vyhlazené.

Rastrový obrázek

Naopak rastrový obrázek, např ve formátu JPEG (když jej zjednodušíme a pomineme ztrátový algoritmus komprese), se skládá pouze z pixelů a jejich barvy. Pokud takový obrázek zvětšíme, základní algoritmus zdvojí počet pixelů, ale ty vycházejí pouze z původní informace, a tedy bude obraz ošklivě rozkostičkovaný a v lepším případě rozmazaný. O jelikož se hustota pixelů obrazovek stále zvyšuje, můžeme si být jistí, že uživatelé naši aplikaci zvětšovat budou.

Ukažme si, jak to vypadá, když se zvětší rastrový obrázek:

Ukázka zvětšení rastrového obrázku

A zde příklad zvětšení vektorového obrázku:

Ukázka zvětšení vektorového obrázku

Kdy použít vektorovou a kdy rastrovou grafiku?

Takže nyní máme představu, jaký je rozdíl mezi vektorovou a rastrovou grafikou. Nemůžeme říci, že jedna je lepší než druhá. Zjednodušeně můžeme říci, že na ikony bychom měli používat vektorové obrázky a na fotografie dostatečně kvalitní obrázky rastrové. Shrňme si nyní do pár bodů základní rozdíly:

Vektorová grafika

  • Jednodušší grafika jako ikony
  • Jakýkoliv grafický prvek, který se bude dynamicky zmenšovat či zvětšovat
  • Možnost i případné animace
  • Lze i dynamicky měnit barvu jednotlivých prvků v obrazci
  • Menší velikost souboru s obrázkem
  • Náročnější na výpočetní výkon

Rastrový obrázek

  • Tam, kde se jedná o reálnou fotografii, či složité obrazce
  • Tam, kde bude obraz vždy v nativním rozlišení, a nebude se s ním zoomovat
  • Kde je třeba detailního, fotorealistického obrázku se stíny a nasvícením, ale není výhodné zatěžovat GPU/CPU velmi složitou scénou
  • Vyšší nároky na velikost souboru
  • Výpočetní nenáročnost

Jak ve WPF pracovat s vektorovou grafikou

Naši partneři možná hledají právě tebe!

Jak možná již tušíte, standardně bez dalších rozšiřujících balíčků WPF ve Visual Studiu nepodporuje externí soubory vektorové grafiky. To jsou např.:

  • .svg - Scalable Vector Graphics
  • .eps, .ps - PostScript
  • .ai - Adobe Illustrator Artwork
  • .cdr - Corel Draw
  • .pdf - Portable Document Format

Zejména soubor SVG je v dnešní době etalon, který se uchytil ve webové grafice, a umí mimo jiné i animace. Bohužel je podporován až v novější verzi Creator's Update (tedy verze OS Windows 10 1709 z konce roku 2017) pod UWP (Universal Windows Platform), kde pro něj vznikla nová třída SvgImageSource.

Jak tedy na vektorovou grafiku ve WPF?

XAML

Řešením je XAML, který v základu využívá nástroje na kreslení jako <Rectangle>, <Line>, <Ellipse> a další, které se vykreslují jako vektorové objekty. S kreslením tvarů jsme se v našem kurzu již setkali. Nyní si ukážeme i další tvary a jak do XAML zkonvertovat SVG soubory.

Vytvoření aplikace

Začneme pracovat na aplikaci, která bude ve výsledku vypadat takto:

Vytvořte si nový projekt a přepněte se do XAML části:

Zde si vytvoříme <Grid>, a ten rozdělíme na 9 rovnoměrných "chlívečků" s těmito parametry:

<Grid.ColumnDefinitions>
    <ColumnDefinition Width="1*"/>
    <ColumnDefinition Width="1*"/>
    <ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
    <RowDefinition Height="1*"/>
    <RowDefinition Height="1*"/>
    <RowDefinition Height="1*"/>
</Grid.RowDefinitions>

To nám rozdělí pracovní plochu na 3 * 3 chlívečky, které si budou díky parametru * udržovat poměr s velikostí okna. Okno by mělo vypadat v návrháři takto (objekty přidáme samozřejmě později):

Vložení jednotlivých prvků

Nyní si ukažme, jak vykreslíme základní tvary.

Rectangle

Jako první vložíme obdélník <Rectangle>, vyplněný zelenou barvou a se žlutým okrajem:

<Rectangle Stroke="Bisque" StrokeThickness= "5" Fill="Aquamarine" Margin="10" Grid.Row="0" Grid.Column="0" />

Výsledek:

Stroke je barva okraje, StrokeThickness je síla čáry okraje v pixelech. Fill je barva výplně, Margin je odskok od okrajů, Grid.Row a Grid.Column určuje, ve kterém z našich "chlívečků" bude obrazec umístěný.

Rectangle - Čtverec

Druhý obdélník je speciální v tom, že je to vlastně čtverec. Hlídá si zde svou aktuální šířku, a tu nastavuje i pro výšku. Toho dosáhneme přiřazením Binding:

<Rectangle StrokeThickness= "5" Margin="10" Grid.Row="1" Grid.Column="0" Width="{Binding ActualHeight, Mode=OneWay, RelativeSource={RelativeSource Mode=Self}}" Stroke="Black">

Výsledek:

Binding může nahrazovat konstantní hodnotu v kterémkoliv parametru proměnnou nebo referencí na jinou proměnou, v našem případě na aktuální výšku obdélníku: Width="{Binding ActualHeight, Mode=OneWay, RelativeSource={RelativeSource Mode=Self}}"

Ellipse

Poté tu máme <Ellipse>, kde je nastavení stejné jako v případě čtverce, ale okořenil jsem to efekty přechodů, jak pro výplň Fill, tak pro okraje Stroke:

<Ellipse StrokeThickness= "5" Margin="10" Grid.Row="0" Grid.Column="1">
    <Ellipse.Stroke>
        <LinearGradientBrush>
            <GradientStop Color="#FFFFFF03" Offset="0"/>
            <GradientStop Color="#FF000CFF" Offset="1"/>
        </LinearGradientBrush>
    </Ellipse.Stroke>
    <Ellipse.Fill>
        <RadialGradientBrush>
            <GradientStop Color="#FF0633FF" Offset="0"/>
            <GradientStop Color="Red" Offset="1"/>
            <GradientStop Color="#FFFFF500" Offset="0.7"/>
            <GradientStop Color="#FF3AFF00" Offset="0.403"/>
            <GradientStop Color="#FFFF16B5" Offset="0.837"/>
        </RadialGradientBrush>
    </Ellipse.Fill>
</Ellipse>

Výsledek:

Pro čáru Stroke využíváme lineární přechod, tedy postupný přechod, v tomto případě mezi dvěma barvami, od spodní modré, po horní žlutou. Color nastavuje logicky barvu, a Offset výchozí pozici na barevné škále – neboli jaké místo bude pro danou barvu vyhrazeno. Postupuje se po 0.1 krocích nebo jemnějších, maximální hodnota je 1. Výplň Fill jsme pro změnu nastavili na přechod několika barev, tentokráte na kruhový přechod.

Ellipse - Kruh

Nyní opět pomocí Bindingu nakreslíme místo elipsy kruh. Postup je totožný jako u našeho čtverce:

<Ellipse x:Name="ellipse" Stroke="Black" Fill="AliceBlue" Margin="10" Grid.Row="1" Grid.Column="1" Width="{Binding ActualHeight, Mode=OneWay, RelativeSource={RelativeSource Mode=Self}}"/>

Pokračovat budeme příště.


 

 

Článek pro vás napsal Michal Kotek
Avatar
Jak se ti líbí článek?
3 hlasů
Autor se věnuje programování již od útlých let, aktuálně programuje rok v .NET framework pomocí C#.
Předchozí článek
3D grafika v C# .NET WPF - Koule a hrany
Všechny články v sekci
Okenní aplikace v C# .NET WPF
Miniatura
Následující článek
Vektorová grafika v C# .NET WPF - Kreslení dalších tvarů
Aktivity (4)

 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!