Grafika přes WPF a síla čáry   zodpovězená otázka

WPF

Dobrý den,

měl bych jeden možná triviální dotaz co se týče nastavení síly zobrazované čáry.WPF je bezesporu velmi zajímavá záležitost, nicméně předtím jsem pracoval převážně s WinForms a teď s WPF jsem teprve v začátcích.

Když jsem ve WinForms a GDI+ potřeboval vykreslit čáru o síle 1px, krásně, čistě a "ostře" to šlo. Ve WPFku se mi to zatím ale moc nedaří. Čáry spíš připomínají "baldy" a nejde mi nastavit aby byly tlusté jen 1px jako ve WinForms. Co zatím vím, je že WPF pracuje s dpi, ale nenapadá mě jak ho tím donutit aby na každém monitoru ta čára byla tlustá fakt jen 1px (jedná se o podkladový rastr, který když je tlustý vypadá hrozně)

Díky moc za přípaqdnou radu a odpověď

zdraví, jaspee

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Ve WPF jsou všechny jednotky v Device Independent Pixel, což je 1/96 palce. Pokud nemá uživatel standardní DPI 96, pak neplatí 1 DIP = 1 pixel.

Musíte to přepočítat, ve WPF je na to funkce:

Window MainWindow = Application.Current.MainWindow;
PresentationSource MainWindowPresentationSource = PresentationSource.FromVisual(MainWindow);
Matrix m = MainWindowPresentationSource.CompositionTarget.TransformToDevice;
DpiWidthFactor = m.M11;
DpiHeightFactor = m.M22;
nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Tomáši, moc Vám děkuji za vysvětlení a přepočtovou funkci.

Zítra ihned vše řádně otestuji.

Jestli vše dobře chápu, dalo by se tedy říci že pokud bude standardní DPI=96, tak nastavení síly 1px = právě 1/96 = koeficient thickness ne 1 pro 1px ale 1/96=(0.01041666)?

Pokud bude DPI jiné (dopředu nevím jaké) je nutno použít výše uvedenou Vaši funkci k jeho zjištění?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Ne, pokud je DPI 96, tak pokud dáte Thickness="1", tak to bude přesně 1 pixel.

Nastavte to přímo kódem, to bude fungovat na libovolném DPI - ty funkce vrátí, kolikrát musíte tu 1 vydělit, aby to vyšlo přesně 1 pixel.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Díky moc za Vaši reakci!

Bohužel mezitím jsem zkoušel kde co, i desetinná čísla :-) ale ve výsledku když se na to kouknu lupou tak to jsou vždy 2pixely a když se použije zoom té celé grafiky tak při určitém zoomu ta čára zmizí úplně. Ta funkce mi vrací v obou osách hodnotu 1, tak fakt nevím kde může být potíž. Rád bych docílil toho aby čára měla tloušťku jen 1px bez ohledu na míru zvětšení/zmenšení.

Myslíte si že je to reálné toho docílit?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Zkuste místo 1 použít -1. Ve winforms je to trik jak docílit vždy přesně 1px tlustého Pen, nevím, jestli to stejně bude fungovat i ve WPF.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Díky za tip :o) -1 vyzkoušeno, bohužel výsledek je stejný. Prostě WPF si stejně udělá co chce (síla 2px). Nejlepšího výsledku jsem zatím dosáhl když použiji hodnotu DpiHeightFactor / 3 Ale i tak je to takové divné. DPI je 96, DpiHeightFactor vrací 1, takže se vlastně nastavuje šířka na 0.333 Rastr se po spuštění zobrazí sice že čára je tenší (snad 1px) ale když se zoomuje tak jakoby každý "lichý" zoom se rastr zdá jako 1px ale každý "sudý" potom je stejně čára širší. Pořád mi to přijde jako fakt dost divné chování.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Tak co zkusit tohle? Mohlo by to pomoci, WPF totiž umí i jiné jednotky, zkusme tedy místo DIP použít přímo PX:

<Line X1="100" X2="200" Y1="100" Y2="100" Stroke="Black" StrokeThickness="1px"/>

Pomůže to?

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

No fakt, to jsem nevěděl. V Silverlightu tohleto není a ve WPF jsem to nikdy nehledal.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Je to velmi šikovné, cm používám neustále, při generování Visuals, které jsou určené k tisku.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Tohle dělá ten jejich antialiasing. Ještě se musí dát RenderOptions.EdgeMode="Aliased", aby se něj vykašlal.

<Line X1="10" X2="150" Y1="20" Y2="20" Stroke="Black" RenderOptions.EdgeMode="Aliased" SnapsToDevicePixels="True"  />

Pokud StrokeThickness nastavíte jako ten WidthFactor a HeightFactor, bude to fungovat všude.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Pánové,

díky moc za pomoc! Konečně se dílo zdařilo :o)

samotné "1px" ještě nezafungovalo, ale bylo to tím jejich antialiasingem. Když se vypne, jak psal Tomáš, čára je jak vyšitá. Navíc ten antialiasing "prasí" i barvu protože černá bez něj je fakt černá.

Kdyby někoho trápil podobný problém, přikládám rekapitulaci je z toho vidět přímo graficky ten rozdíl.

<Line X1="10" X2="150" Y1="20" Y2="20" Stroke="Black" RenderOptions.EdgeMode="Aliased" SnapsToDevicePixels="True" StrokeThickness="1" />
        <Line X1="10" X2="150" Y1="40" Y2="40" Stroke="Black" RenderOptions.EdgeMode="Aliased" SnapsToDevicePixels="True" StrokeThickness="2" />
        <Line X1="10" X2="200" Y1="100" Y2="100" Stroke="Black" StrokeThickness="1px"/>

První 2čáry jsou bez antialiasingu, poslední je ta původní hrůza.

Ještě jednou díky moc !

Je skvělé že vbnet tu je :o)

Ať se Vám všem daří !

Petr

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Podle mě kdyby člověk nastavil Y souřadnici na 19.5 a tloušťku 1, tak to bude to samé. Protože WPF bere Y jako prostředek té čáry a když má tedy tloušťku 1 pixel, tak jde de facto od 19.5 do 20.5, což znamená, že pixely 19 i 20 vybarví šedě, protože jsou z poloviny černé. Proto je ta čára tlustší a šedá.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback