Net-Base Magazín

18.08.2026

VCL High-DPI: škálovanie ikon za behu a zabránenie rozmazaniu pixelov v TImageList

High-DPI vo VCL nie je len zaškrtávacie políčko, ale reťazec nastavení ImageList, udalostí zmeny DPI a čistého vykresľovania. Tento praktický článok ukazuje, ako škálovať ikony za behu, vyhnúť sa artefaktom a reprodukovateľne debugovať typické pasce TImageList.

18.08.2026

Od témy magazínu k projektovej praxi

Súvisiace stránky služieb a technológií k príspevku

Ktokoľvek prevádzkuje VCL-aplikácie na moderných Windows-klientoch, narazí skôr alebo neskôr na ten istý príznak: ikony pri 125 %/150 %/200 % pôsobia rozostrené, ošúchané alebo majú sivý okraj. Práve tu je téma VCL High-DPI Icons praktická: nie preto, že by High-DPI bolo nové, ale preto, že sa problémy väčšinou prejavia až v bežnej prevádzke – na Terminalservern, pri prepínaní notebooku medzi dokom alebo ak má každý monitor inú DPI.

Jadro problému zriedka spočíva v tom, že je PNG poškodené, skôr je to pipeline: odkiaľ ikona pochádza (Ressource, Datei, SVG, Font), v akom rozlíšení je dodaná, ako sa dostane do der TImageList a kto kedy ako škáluje. Vo VCL sa pritom stretáva niekoľko pojmov, ktoré treba rozlíšiť: DPI-Awareness (či Windows škáluje aplikáciu alebo sa aplikácia škáluje sama), Per-Monitor-DPI (každý monitor môže byť iný) a ImageList-Strategie (mať pripravené viacero Auflösungen alebo rastrovať za behu).

V tomto článku nejde zámerne o debaty UI-dizajnu, ale o čistý, prevádzkovo bezpečný prístup: škálovať ikony za behu tak, aby sa nestali pixelovou kašou, aby zostali intaktné Alpha-Kanäle a aby výmeny DPI fungovali bez blikajúcich alebo nesprávnych Bildgrößen. K tomu patria nástrahy, tipy na ladenie a úprimné zhodnotenie, kedy sa dodatočná práca oplatí.

Prečo vzniká pixelová kaša: pochopenie škálovacej reťaze vo VCL

Grafik zur Icon-Skalierung: Master-Icon wird in mehrere Zielgrf6dfen gerastert, doppelte Skalierung ffchrt zu Unsche4rfe
Jednorazové škálovanie z hlavného zdroja je kontrolovateľné — duplicitné resamplingové kroky rýchlo vedú k viditeľnému rozostreniu.

Najčastejším dôvodom neostrých ikon je jednoeinmaliges Down-/Upscaling v nesprávnom čase. Klasický priebeh v Legacy-VCL:

  • Aplikácia dodáva ikony iba v 16×16 alebo 24×24.
  • Windows alebo VCL škáluje na 20×20 / 32×32 / 48×48.
  • Škálovač používa interpoláciu, ktorá je pre fotografie v poriadku, ale pri pixelgrafike rozmazáva hrany.
  • Navyše sa priehľadnosť (Alpha) zovrie do maskovacej logiky alebo sa konvertuje viackrát.

Obzvlášť nepríjemné je, keď prebieha viacero škálovaní po sebe: napríklad keď ImageList už poskytuje škálované bitmapy a Windows kvôli DPI-unaware alebo systémovému DPI opäť škáluje. Výsledok: dvojité rozostrenie.

Ďalším v projektoch podceňovaným bodom je der Skalierungs-Zeitpunkt. Pri Per-Monitor-DPI (PMv2, teda Per-Monitor-DPI-Awareness v2) sa môže efektívne DPI zmeniť, keď okno zmení monitor alebo keď Remote-Desktop-Client dynamicky upraví DPI. Ak sa potom eine TImageList alebo cache nesprávne neobnovia, zrazu uvidíte ikony v nesprávnej veľkosti alebo s nesprávnym rastrom.

TImageList unter High-DPI: typische Fallen in echten Anwendungen

TImageList je historicky určená pre malé bitmapy s pevnými rozmermi, indexami a relatívne tuhým spôsobom ukladania. Pri vysokom DPI z toho vznikajú praktické pasce:

1) Pevne viazané Width/Height

Mnoho VCL-formulárov nastaví ImageList.Width/Height už za designovania a nechá to tak. Pri 150% by Windows napríklad chcel z 16 → 24. Ak zostane zoznam na 16, obrázky budú buď orezané, alebo niekde škálované — obe možnosti vyzerajú nechcene.

2) PNG-Alpha und Maskenlogik

Podľa verzie Delphi a použitých VCL-komponentov sa rýchlo ocitnete v hybridnom režime: PNG s alfakanálom sa interne niekedy drží ako 32-bitová bitmapa, inokedy ako Mask+Color. Ak konvertujete viackrát (PNG → Bitmap → ImageList → Draw), vznikajú sivé halo efekty alebo ostré hrany. Efekt je často citlivý na pozadie: na tmavej toolbare vyzerá horšie než na svetlom paneli.

3) DPI-Wechsel zur Laufzeit: Caches, Handles, OwnerDraw

Niektoré kontroly cachujú zobrazenie obrázka alebo preberajú ImageList-handles v čase, keď DPI ešte nie je finálne. Najmä pri paneloch nástrojov, TreeView/ListView a OwnerDraw-scenároch sa po zmene DPI občas objavia nesprávne veľkosti obrázkov alebo prázdne ikony, až kým nenastane Repaint alebo RecreateWnd.

4) Terminalserver und Remote-Desktop als Realitetstest

Ak sa aplikácia používa cez RDP, zmeny DPI a opätovné pripojenia session nie sú zriedkavé. Práve tam sa neodolná ImageList-stratégia prejaví: používateľ po reconnecte vidí rozmazané ikony alebo nesprávne škálované panely nástrojov, hoci lokálne bolo všetko v poriadku.

Čistý prístup: Poskytnúť viacero rozlíšení namiesto brutálneho upscalingu

Najdôležitejšie rozhodnutie je koncepčné: Chcete za behu škálovať ikony z jednej základnej grafiky (napr. 16 → 32), alebo poskytnete viac nativných rozlíšení a podľa DPI vyberiete to vhodné?

V praxi takmer vždy vyhráva prístup „viacero rozlíšení“. Upscaling má zmysel, ak je zdroj vektorový (SVG, Icon-Font) alebo ak potrebujete len mierne faktory. Ak výrazne zväčšujete z malej rastrovej grafiky, stratíte kvalitu hrán, čo je na moderných displejoch okamžite viditeľné.

Vo VCL-svete sú pre tento prístup dnes relevantné dva stavebné kamene:

  • TImageCollection: kontajner pre obrázky v niekoľkých veľkostiach/variantoch.
  • TVirtualImageList: z toho za behu generuje ImageList v aktuálne potrebnej veľkosti a reaguje na zmeny DPI.

To vám neodstráni všetky problémy, ale presunie riešenie na správne miesto: definujete zdroje obrázkov čisto a škálovanie/selektovanie prebieha konzistentne.

VCL High-DPI: Kedy má zmysel škálovať ikony za behu (a kedy nie)

Sú legitímne dôvody, prečo ikony škálovať za behu:

  • Načítavate ikony dynamicky (napr. z plugin-folderu, zákazníckych branding-pakov alebo konfiguračných balíkov).
  • Chcete jednotnú pipeline pre rôzne zdroje (ICO, PNG, SVG) a nechcete viazať všetky varianty už pri build-e.
  • Generujete ikony programovo (stavové odznaky, overlaye, komponované symboly).

Nema zmysel robiť škálovanie za behu, ak máš v skutočnosti len klasické Toolbar-Icons z pevnej sady. V takom prípade je najmenej náročný na údržbu spôsob: dodať viacero rozlíšení a nechať VCL vybrať správne.

Ak robíš škálovanie za behu, rob to podľa jasných pravidiel:

  • Nikdy z už raz skalovaného bitmapu znovu neskalovať. Vždy vychádzaj z hlavného zdroja (ideálne vektorový alebo vysoko rozlíšený).
  • Cache pre cieľovú veľkosť a DPI, inak budeš pri každom vykreslení znovu škálovať — to stojí CPU a môže spôsobovať trhanie.
  • Zachovať alpha kanál: minimalizovať konverzie, nastaviť 32-bit RGBA, pozadie nerasterizovať.

Pragmatická architektúra: Icon‑pipeline ako samostatný komponent

Vo väčších aplikáciách sa oplatí tému nerozptyľovať po celom kóde, ale postaviť malú pipeline. Nemusí to byť framework — skôr jasne definovaná zodpovednosť:

  • Icon‑zdroj: Odkiaľ pochádzajú master‑assety (zdroje, súbory, databáza, API)?
  • Rasterizer/Scaler: Ako sa z master‑zdroja generuje cieľová veľkosť (interpolácia, prípadne SVG‑render)?
  • Cache: Kľúč (Icon‑ID, cieľové pixely, DPI, theme) a životný cyklus (invalidovať pri zmene DPI, zmene theme, zmene balíka).
  • Consumer‑adapter: Ako sa výsledok dostane do VCL štruktúr (TImageList/TVirtualImageList, OwnerDraw, PaintBox)?

Výhoda: DPI‑bugy môžeš reprodukovateľne debugovať na jednom mieste, namiesto hľadania „kde sa to ešte raz škaluje“ v 40 formulároch.

Správne spracovať zmenu DPI: udalosti, rebuild, repaint

Notebook mit zwei Monitoren unterschiedlicher DPI, Fensterwechsel zeigt unterschiedliche Icon-Grf6dfen in einer Desktop-App
Per‑Monitor‑DPI je realitný test: pri prepnutí monitora musí icon‑pipeline znovu rasterizovať, nie len znovu vykresliť.

Pod Windows je zmena DPI vlastný životný cyklus. Vo VCL sú podľa verzie a DPI‑awareness rôzne udalosti/mechanizmy, ale základný princíp zostáva:

  • Keď sa zmení DPI okna, obrazové zdroje, ktoré majú byť pixelovo presné, musia byť znovu pripravené.
  • Ak dynamicky plníš ImageLists, často nestačí obyčajné Invalidate — potrebuješ Rebuild obrázkov v novej cieľovej veľkosti.

Praktický vzor: pri zmene DPI (napr. Form‑Scale/prehodenie monitora) invaliduješ icon‑cache pre dané DPI a znovu zostavíš postihnuté ImageLists. Dôležité je neskalovať v paint‑eventoch, ale robiť to v kontrolovanom update‑bloku (Toolbar.BeginUpdate/EndUpdate, vypnúť ListView‑Redraw, potom znova zapnúť). Tak sa vyhneš blikaniu a nedokončeným UI stavom.

Prečo je TImageList často neostrý: interpolácia, zaokrúhľovanie DPI, hrany

Keď pochopíš, že problém nie je samotné DPI, ale interpolácia plus zaokrúhľovanie, dá sa veľa efektov vysvetliť:

  • Zaokrúhľovanie DPI: 125 % nie je čisté zdvojnásobenie. Z 16 px vznikne 20 px (16 * 1,25). Z 24 px vznikne 30 px. To sú neliché čísla, ktoré sťažujú ostré hrany pixelov.
  • Resampling-Filter: Bilinear/Bicubic robí hrany mäkšími. To je pre fotky v poriadku, pre ikony často nie.
  • Subpixel-Effekte: Windows môže v závislosti od renderovacej cesty používať Subpixel-Antialiasing alebo nie. Pri ikonách chcete kontrolované hrany — a ideálne žiadne viacnásobné stupne filtrovania.

Ak máte rastrové ikony, je v mnohých tímoch bežnou praxou dodávať pre každú cieľovú veľkosť vlastné PNG (16/20/24/32/40/48). Znie to ako veľa, no často je to menej práce, než roky debugovať „prečo to na tomto monitore vyzerá divne“.

Debugging: Urobiť problém s rozmazanými pixelmi reprodukovateľným namiesto opráv podľa odhadu

Pracovisko s poznámkami k ladeniu pre škálovanie ikon a testy pozadia vo vzťahu k alfa hrane
Dobre rutiny ladienia DPI testujú veľkosti, pozadia a časové momenty rebuildov — nielen prvý screenshot.

Chyby pri High-DPI často pôsobia náhodne. S niekoľkými kontrolami sa dajú spraviť deterministickými:

1) Logovanie DPI a veľkostí ImageList za behu

Logujte pri štarte a pri zmene DPI: CurrentPPI formulára, Screen.PixelsPerInch (pozor: môže to byť systémové DPI), ako aj ImageList.Width/Height postihnutých zoznamov. Ak po zmene monitora stále vidíte 16 px, hoci očakávate 32 px, príčina je jasná: chýba Rebuild alebo príde príliš neskoro.

2) Ikony dočasne zväčšiť

Rýchly test je nastaviť ikonám na paneli nástrojov dočasne 48 px. Zlá skalácia na seba upozorní okamžite. Dobre nastavené pipeline zostanú aj pri 48 px ostré, lebo rasterizujú zo zdrojovej veľkosti.

3) Testovať zmeny témy a pozadia

Halo efekty na hrane sú často problém s alfa/premultiply. Testujte na svetlom/tmavom pozadí a na plochách s prechodom farieb. Ak hrana vyzerá inak v závislosti od pozadia, spracovanie priehľadnosti nie je správne.

4) Remote Desktop / zmena monitora ako testovací skript

Vytvorte krátky testovací skript pre QA: spustiť aplikáciu na monitore A (100 %), presunúť okno na monitor B (150 %), späť, potom RDP reconnect. Ak to funguje stabilne, vyriešite veľa problémov u zákazníkov.

Migrácia v existujúcich aplikáciách: krokovo namiesto Big Bang

V narastajúcich Delphi-VCL aplikáciách je logika ikon často rozptýlená na mnohých miestach: menu, panely nástrojov, ActionLists, TreeViews, stavové indikátory. Kompletná prestavba na jedenkrát prináša riziko. Overený prístup je krokové nasadenie:

  • Inventár: Aké ImageListy existujú? Ktoré ovládacie prvky ich používajú? Aké veľkosti sa očakávajú?
  • Prioritizovať: Najprv najviditeľnejšie plochy (hlavný toolbar, navigácia, kontextové menu).
  • Jednotný zdroj: Centralizovať ikony (ImageCollection alebo vlastný loader) namiesto načítavania jednotlivých súborov v každom formulári.
  • Testovanie pri zmene DPI: Od prvého prerobeného modulu dôsledne vykonávať testy pri zmene DPI.

Dôležité: Ak prevádzkuješ súbežne starú a novú pipeline, zdokumentuj jasné pravidlá. Inak vznikne zmiešané prostredie, v ktorom sú niektoré ikony ostré a iné viditeľne neostré.

Performance und Speicher: Laufzeit-Skalierung ohne Nebenwirkungen

Škálovanie stojí CPU a pamäť. V business softvéri si toho v pokoji málokedy všimneš, ale pri presúvaní okna na nový monitor alebo pri štarte s mnohými formami to môže klesať plynulosť. Tri praktické vodidlá:

  • Cache-Größen begrenzen: Neuchovávaj každú medziúroveň naveky. Ak potrebuješ len 100% a 150%, cacheuj len tieto.
  • Lazy Build: Ikony rasterizuj až vtedy, keď ich obrazovka naozaj potrebuje. Pri veľkých menu to ušetrí čas pri štarte.
  • Batch-Rebuild: Pri zmene DPI netriggeruj každé control jednotlivo. Centrálne rebuildovanie zabráni redundantnému škálovaniu.

Ak pracuješ s TVirtualImageList, je veľa z toho už koncepčne pokryté, ale aj tak musíš dávať pozor, aby si si navyše nevytváral vlastné škálovanie navrchu.

Fallback-Strategien: Was tun, wenn nicht alle Icon-Größen vorliegen?

V realite nemáš vždy všetky assety vo všetkých veľkostiach. Potrebuješ jasnú fallback-stratégiu, aby si predišiel náhodným výsledkom:

  • Prefer Downscale: Radšej downscalovať z 64 px na 32 px než upscalovať z 16 px na 32 px.
  • Definiere Stufen: Urči, ktoré cieľové veľkosti naozaj podporuješ (napr. 16/20/24/32/40/48) a mapuj na ne DPI konzistentne.
  • Transparenz testen: Pri fallbackoch dávaj pozor na alfa kanál — práve tam vznikajú halo efekty.

Typická chyba je vziať jednoducho nejakú nasledujúcu veľkosť. Vnímaná ostrosť sa tým líši podľa ikony. Lepšie je mať pevný, zdokumentovaný mapping plán.

Wann lohnt sich der Aufwand wirklich?

Sú tri jasné indikátory, že sa oplatí čistá High-DPI-ikonová pipeline:

  • Tvoji používatelia pracujú s kombinovanými monitormi (laptop + externý) alebo často cez RDP.
  • Aplikácia je dlhodobá a bude sa udržiavať roky — vnímanie UI je súčasťou akceptácie.
  • Máš plánované modernizačné kroky (zvýšiť DPI-Awareness, vymeniť controllery, prerobiť toolbar-layout).

Ak aplikácia beží iba na pevnom kiosk-systéme s identickou rozlíšením, môžeš to držať minimálne: dodať vhodnú icon-velkosť, nastaviť DPI-Awareness správne a hotovo.

Fazit: High-DPI ist kein kosmetisches Detail, sondern eine Rendering-Entscheidung

Neostré ikony v VCL zriedka predstavujú izolovanú chybu; sú skôr indikátorom nečistej reťaze zdrojov, škálovania a cacheovania. Najrobustnejší prístup je poskytovať ikony v niekoľkých rozlíšeniach a distribuovať ich cez centrálnu pipeline (napr. ImageCollection/VirtualImageList alebo vlastná ikonová vrstva) konzistentne. Laufzeit-Skalierung má zmysel, keď máš dynamické zdroje alebo zložené symboly, ale len s master-zdrojom, DPI-založeným cacheom a jasnými pravidlami pre rebuild.

Ak máš konkrétne symptómy (DPI-zmena rozbije ikony, halo na okraji, nesprávne veľkosti po RDP), oplatí sa problém cielene izolovať a riešiť ako malý architektonický modul namiesto kopenia workaroundov vo forme. Ak pri tom potrebuješ podporu pri debuggingu alebo pri postupnej modernizácii, nájdeš tu vhodný vstup: Kontakt zur Net-Base Software GmbH.

Pre túto tému sú dôležité aj Timagelist High Dpi a Delphi Vcl Dpi-Awareness. Článok tieto aspekty zrozumiteľne usporiada a ukáže, na čo v každodennej praxi záleží.

Prediskutovať projekt alebo modernizačný zámer s Net-Base.

ďalší krok

Keď sa z témy stane reálny projekt, architektúru, existujúci stav a prevádzku treba včas posudzovať spoločne.

Podporujeme nielen pri jednotlivých otázkach, ale aj vtedy, keď sa z fragmentov zdrojového kódu, tém súvisiacich s legacy systémami alebo nápadov na portál má stať robustný podnikový projekt.

  • Stav, cieľový obraz a technické riziká sa hodnotia spoločne.
  • REST, prístup k údajom, portály a nasadenie nebudú odložené na neskôr ako následné úlohy.
  • Včas identifikujete, ktorá cesta je ekonomicky a prevádzkovo životaschopná.

Zdieľať príspevok

Tento príspevok priamo zdieľať

LinkedIn, X, XING, Facebook, WhatsApp a e‑mail sú okamžite k dispozícii. Pre Instagram pripravíme priamo odkaz a stručný text.

E-mail

Instagram sa otvorí v novej karte. Odkaz a krátky text sa predtým skopírujú do schránky.