Net-Base Magazin

18.08.2026

VCL High-DPI: ikonok futásidőbeni skálázása és a TImageList pixeles elmosódásának elkerülése

High-DPI a VCL-ben nem csupán egy jelölőnégyzet, hanem egy lánc az ImageList-beállításokból, a DPI-váltási eseményekből és a tiszta renderelésből. Ez a gyakorlati cikk megmutatja, hogyan skálázd az ikonokat futásidőben, hogyan kerüld el a vizuális artefaktumokat, és hogyan hibakeresd reprodukálhatóan a tipikus TImageList-csapdákat.

18.08.2026

A magazintémától a projektgyakorlatig

A bejegyzéshez tartozó szolgáltatási és technikai oldalak

Akinek VCL-alkalmazásai futnak modern Windows-klienseken, előbb vagy később ugyanabba a tünetbe ütközik: az ikonok 125%/150%/200% esetén elmosódottnak, szálkásnak tűnnek vagy szürke peremet kapnak. Pont itt válik a VCL High-DPI ikonok témája gyakorlativá: nem azért, mert a High-DPI új lenne, hanem mert a problémák általában csak a napi üzem során jelentkeznek — terminálszervereken, notebook dokkolásnál vagy amint monitoronként eltérő DPI-k lépnek fel.

Az alapvető probléma szinte sosem az, hogy „a PNG tönkrement“, hanem a pipeline: honnan származik az ikon (Ressource, Datei, SVG, Font), milyen méretben szolgáltatják, hogyan kerül a TImageList-be és ki mikor hogyan skáláz. A VCL-ben több fogalom találkozik, amelyeket el kell különíteni: DPI-Awareness (hogy Windows vagy az alkalmazás maga skáláz-e), Per-Monitor-DPI (minden monitor eltérhet) és ImageList-stratégia (több Auflösungen előtartása vagy futásidőben raszterezés).

Ebben a cikkben szándékosan nem az UI-design vitákról van szó, hanem egy tiszta, üzembiztos megközelítésről: ikonok futásidőbeli skálázásáról úgy, hogy ne legyenek pixelmásszá, hogy az Alpha-Kanäle sértetlenek maradjanak és hogy a DPI‑váltások villogás vagy hibás képméretek nélkül működjenek. Emellett ismertetünk csapdákat, hibakeresési javaslatokat és egy őszinte értékelést arról, mikor éri meg a többletmunka.

Miért alakul ki pixelmaszat: a VCL skálázási láncának megértése

Ábra az ikon skálázásáról: a master-ikont több célméretre raszterezik, a dupla skálázás elmosódáshoz vezet
Egy egyszeri skálázás egy master-forrásból kontrollálható — a többszörös resampling-lépések gyorsan látható elmosódáshoz vezetnek.

A homályos ikonok leggyakoribb oka egy egyszeri le-/felméretezés a rossz időpontban. Klasszikus menetrend Legacy‑VCL esetén:

  • Az alkalmazás csak 16×16 vagy 24×24 ikonokat ad.
  • Windows vagy a VCL skáláz 20×20 / 32×32 / 48×48 értékekre.
  • A skálázó interpolációt használ, ami fényképekhez rendben van, de pixelgrafikánál elmoshatja a kontúrokat.
  • Ráadásul az átlátszóság (Alpha) maszklogikába kényszerül vagy többször konvertálódik.

Különösen kellemetlen, ha több skálázás követi egymást: például amikor az ImageList már egy skálázott bitmapot ad, és Windows DPI-unaware vagy rendszer‑DPI miatt még egyszer átskáláz. Eredmény: dupla elmosás.

Egy másik, projektekben alulértékelt tényező a skálázás időzítése. Per-Monitor-DPI (PMv2, azaz Per-Monitor-DPI-Awareness v2) esetén a hatékony DPI megváltozhat, ha egy ablak monitort vált vagy ha egy Remote-Desktop kliens dinamikusan állítja a DPI-t. Ha ekkor egy TImageList vagy egy cache nincs helyesen újraépítve, hirtelen hibás méretű vagy rossz raszterű ikonokat látunk.

TImageList alatt High‑DPI esetén: tipikus csapdák valódi alkalmazásokban

A TImageList történelmileg kis bitmapokhoz készült, rögzített méretekkel, indexekkel és viszonylag merev tárolási logikával. High-DPI környezetben ebből gyakorlati csapdák adódnak:

1) Fixre bekötött Width/Height

Sok VCL-űrlap beállítja az ImageList.Width/Height értékét design-time-ban és így is hagyja. 150% esetén Windows például inkább a 16×16-ból 24×24-et szeretne készíteni. Ha a lista 16×16 marad, akkor vagy levágás (clipping) történik, vagy máshol történik a skálázás — egyik sem esztétikus.

2) PNG-alfa és maszkolási logika

Az Delphi-verziótól és a VCL-komponensektől függően könnyen keveredésbe kerülhetsz: az alfa-csatornás PNG-ket belsőleg néha 32-bites bitmapként, néha Mask+Color formátumban tartja a rendszer. Amint többször konvertálsz (PNG -> Bitmap -> ImageList -> Draw), szürke aurák vagy kemény élek jelennek meg. A hatás gyakran a háttértől függ: egy sötét eszköztáron rosszabbul látszik, mint egy világos panelen.

3) DPI-váltás futásidőben: cache-ek, handle-ök, OwnerDraw

Néhány komponens cache-eli a képmegjelenítést, vagy átveszi az ImageList-handle-öket olyan időpontban, amikor a DPI még nem végleges. Különösen toolbareknál, TreeViews/ListViews-nál és OwnerDraw-szcenáriókban DPI-váltás után időnként hibás képméreteket vagy „üres” ikonokat látsz, amíg meg nem történik egy Repaint vagy RecreateWnd.

4) Terminalserver és Remote-Desktop mint valóságteszt

Ha az alkalmazást RDP-n keresztül használják, a DPI-váltások és session-reconnectok nem ritkák. Pont ott csap vissza egy nem robusztus ImageList-stratégia: a felhasználó a reconnect után elmosódott ikonokat vagy rosszul skálázott eszköztárakat lát, még ha lokálisan minden rendben volt is.

Tiszta megközelítés: több felbontás szolgáltatása a brutális felskálázás helyett

A legfontosabb döntés koncepcionális: futtatás közben egyetlen alapgrafikából szeretnél-e felskálázni (például 16×16 -> 32×32), vagy több natív felbontást kínálsz, és DPI-től függően választod ki a megfelelőt?

Gyakorlatban szinte mindig a több felbontás megközelítés a nyerő. Felskálázást akkor érdemes alkalmazni, ha a forrás vektoralapú (SVG, icon-font), vagy ha valóban csak mérsékelt skálafaktorokra van szükség. Amint egy kis raszterképet erősen felskálázol, elveszíted az élek minőségét, és ezt a modern kijelzőkön azonnal látni fogod.

A VCL világában ma ehhez elsősorban két építőelem releváns:

  • TImageCollection: konténer a képek több méretben/variánsban történő tárolásához.
  • TVirtualImageList: ebből futásidőben létrehoz egy ImageList-et a jelenleg szükséges méretben, és reagál a DPI-változásokra.

Ez nem szüntet meg minden problémát, de a problémát a megfelelő helyre helyezi: tisztán definiálod a képeket, és a skálázás/selektálás konzisztensen történik.

VCL High-DPI ikonok futásidőbeli skálázása: mikor érdemes (és mikor nem)

Vannak jogos indokok, hogy ikonokat futásidőben skálázz:

  • Dinamikusan töltöd be az ikonokat (például egy plugin-mappából, ügyfél-specifikus branding-csomagokból, konfigurációs csomagokból).
  • Egységes pipeline-t szeretnél különböző forrásokhoz (ICO, PNG, SVG), és nem akarod a minden variánst build-időben kötni.
  • Programból generálsz ikonokat (állapotjelzők, overlay-ek, összetett szimbólumok).

A futásidejű méretezés nem ésszerű, ha valójában csak klasszikus eszköztár-ikonokat használsz egy rögzített készletből. Ilyenkor a legkevesebb karbantartást igénylő megoldás: több felbontás gondos kiszolgálása, és a VCL-re bízni a választást.

Ha futásidejű méretezést alkalmazol, akkor egyértelmű szabályok szerint:

  • Soha ne skálázz újra egy már egyszer skálázott bitmapot. Mindig egy master-forrásból indulj ki (ideális esetben vektor alapú vagy nagyfelbontású).
  • Gyorsítótár célméretenként és DPI-nként, különben minden Paint során újraskálázol — ez CPU-t fogyaszt és akadozást okozhat.
  • Alpha megtartása: minimalizáld a konverziókat, használj 32 bites RGBA-t, a háttér ne legyen raszterizálva.

Pragmatikus architektúra: ikon-pipeline mint külön komponens

Nagyobb alkalmazásoknál érdemes a témát nem szétoszlatni, hanem egy kis pipeline-t építeni. Nem kell belőle framework — inkább egy világos felelősségi kör:

  • Ikon-forrás: honnan származnak a master-assetek (erőforrások, fájlok, adatbázis, API)?
  • Rasterizer/Scaler: hogyan állítjuk elő a célméretet a masterből (interpoláció, szükség esetén SVG-renderelés)?
  • Cache: kulcs (Icon-ID, célpixel, DPI, Theme) és életciklus (invalidálás DPI-váltásnál, Theme-váltásnál, csomagváltásnál).
  • Consumer-Adapter: hogyan kerül az eredmény a VCL-struktúrákba (TImageList/TVirtualImageList, OwnerDraw, PaintBox)?

Előny: a DPI-hibákat reprodukálhatóan egy helyen tudod debugolni, ahelyett hogy 40 űrlapon keresnéd, hol történik még egyszer a skálázás.

DPI-váltás helyes kezelése: Ereignisse, Rebuild, Repaint

Notebook mit zwei Monitoren unterschiedlicher DPI, Fensterwechsel zeigt unterschiedliche Icon-Grf6dfen in einer Desktop-App
A per-monitor DPI a valóságteszt: monitorváltáskor az ikon-pipeline-t újra raszterizálni kell, nem csak újrarajzolni.

A Windows alatt a DPI-váltások saját életciklust jelentenek. A VCL-ben verziótól és DPI-tudatosságtól függően több esemény/mechanizmus létezik, de az alapelv ugyanaz:

  • Ha az ablak DPI-je megváltozik, a pixelen pontosnak szánt kép alapú erőforrásokat újra kell előállítani.
  • Ha dinamikusan töltöd az ImageList-eket, egy puszta Invalidate gyakran nem elég — szükséged van a képek újraépítésére az új célméretben.

Egy gyakorlatias minta: DPI-változáskor (pl. Form-Scale/monitorváltás) invalidálod az ikon-cache-t az adott DPI-re, és újraépíted a érintett ImageList-eket. Fontos, hogy ne a Paint-eseményekben skálázz, hanem egy kontrollált update-blokkban (Toolbar.BeginUpdate/EndUpdate, ListView-Redraw kikapcsolva, majd vissza). Így elkerülöd a villogást és a félkész UI-állapotokat.

Miért lesz a TImageList olyan gyakran életlen: Interpolation, DPI-Rundung, Kanten

Ha egyszer megérted, hogy nem a DPI a probléma, hanem az interpoláció plusz kerekítés, sok effektus megmagyarázható:

  • DPI-kerekítés: 125a0% nem tiszta duplázó. 16 px-ből 20 px lesz (16 * 1,25). 24 px-ből 30 px lesz. Ezek ferde számok, amelyek megnehezítik a pixelek éleit.
  • Resampling-Filter: Bilinear/Bicubic lágyítja az éleket. Das ist für Fotos ok, für Icons gyakran nem.
  • Subpixel-Effekte: Windows a renderelési útvonaltól függően használhat subpixel-élsimítást vagy nem. Ikonoknál szabályozott éleket akarsz — és lehetőleg ne legyenek többszörös szűrőfokozatok.
  • Ha raszteres ikonjaid vannak, sok csapatnál bevett gyakorlat, hogy célméretenként külön PNG-ket szállítanak (16/20/24/32/40/48). Soknak hangzik, de gyakran kevesebb munka, mint éveken át azt hibakeresni, hogy „miért néz ki furán ezen a monitoron“.

    Hibakeresés: a pixeles elmosódás reprodukálhatóvá tétele a megérzés szerinti javítás helyett

    Arbeitsplatz mit Debug-Notizen ffcr Icon-Skalierung und Hintergrundtests zur Alpha-Kante
    Jó DPI-hibakeresési rutinok tesztelik a méreteket, a háttereket és az újrafordítás időpontjait — nem csak az első képernyőképet.

    High-DPI hibák gyakran véletlenszerűnek tűnnek. Néhány ellenőrzéssel determinisztikussá tehetők:

    1) DPI és ImageList-méretek futásidőben naplózása

    Naplózd indításkor és DPI-váltáskor: a Form CurrentPPI-ját, a Screen.PixelsPerInch-et (figyelem: ez lehet a rendszer DPI-je), valamint az érintett listák ImageList.Width/Height értékeit. Ha monitorváltás után még mindig 16d716-t látsz, pedig 32-t várnál, az ok világos: hiányzik a Rebuild vagy túl későn történik.

    2) Ikonok látható nagyítása

    Egy gyors teszt, ha a toolbar-ikonokat ideiglenesen 48 px-re állítod. A rossz skálázás azonnal feltűnik. Jó pipeline-ok még 48 px-en is élesek maradnak, mert megfelelő forrásból rasztereznek.

    3) Téma- és háttérváltások tesztelése

    A szélén látható halo gyakran alpha/premultiply probléma. Tesztelj világos/sötét témán és színátmenetes felületeken. Ha az él a háttértől függően másként néz ki, akkor a transzparencia-kezelés nincs rendben.

    4) Remote Desktop / monitorváltás mint tesztszkript

    Készíts egy rövid tesztszkriptet a QA számára: indítsd az alkalmazást A monitoron (100%), helyezd az ablakot B monitorra (150%), vissza, majd RDP újracsatlakozás. Ha ez stabil, sok ügyfélprobléma már megoldódik.

    Migráció meglévő alkalmazásokban: lépésenként a Big-Bang helyett

    Gyarapodó Delphi-VCL alkalmazásokban az ikonlogika gyakran sok helyen jelenik meg: menük, toolbárok, ActionLists, TreeViews, státuszsávok. Egy Big-Bang átépítés kockázatos. Bevált egy lépésenkénti megközelítés:

    • Leltár: Milyen ImageList-ek vannak? Mely controllok használják őket? Milyen méreteket várnak el?
    • Prioritás: Először a legszembetűnőbb felületek (főeszköztár, navigáció, kontextusmenük).
    • Egységes forrás: Ikonokat centralizálni (ImageCollection vagy saját loader), ahelyett, hogy formonként külön fájlokat töltenének be.
    • DPI-váltás tesztelése: Az első átalakított modultól kezdve következetesen futtass DPI-váltás teszteket.

    Fontos: Ha párhuzamosan üzemeltetsz régi és új pipeline-t, dokumentálj világos szabályokat. Ellenkező esetben kevert környezet alakul ki, amelyben néhány ikon éles, míg mások szemmel láthatóan homályosnak tűnnek.

    Teljesítmény és memória: Futásidejű skálázás mellékhatások nélkül

    A skálázás CPU-t és memóriát igényel. Egy üzleti szoftvernél ez ritkán látszik tétlen állapotban, de amikor az ablakot új monitorra húzod vagy sok Forms-szal indítod az alkalmazást, akadozás jelentkezhet. Három gyakorlati vezérelv:

    • Cache-méret korlátozása: Ne tartsd örökké minden átmeneti állapotot. Ha csak 100% és 150% kell, tárold cache-ben csak ezeket.
    • Késleltetett generálás: Az ikonokat csak akkor raszteresítsd, amikor a képernyő valóban igényli őket. Nagy menük esetén ez indítási időt takarít meg.
    • Csoportos újragenerálás: DPI-váltásnál ne indíts egyenként minden Controlt. Egy központi rebuild megelőzi a redundáns skálázást.

    Ha TVirtualImageList-t használsz, sok ezek közül koncepcionálisan már megvan, de ügyelj rá, hogy ne építs rá még egy saját skálázási réteget.

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

    A gyakorlatban nem mindig vannak meg az összes eszköz minden méretben. Ilyenkor világos fallback-stratégiára van szükség, hogy elkerüld a véletlenszerű eredményeket:

    • Lehetőleg lefelé skálázás: Inkább skálázd le a 64 px-et 32 px-re, mint hogy egy 16 px-est felskálázz 32 px-re.
    • Határozd meg a szinteket: Rögzítsd, mely célméreteket támogatod ténylegesen (pl. 16/20/24/32/40/48) és térképezd rá a DPI-t tisztán.
    • Transzparencia tesztelése: Fallbackoknál különösen az alfa-csatornára ügyelj — pont ott keletkezhetnek halo-k a széleken.

    Tipikus hiba, ha egyszerűen valamilyen következő méretet választasz. Ettől az ikonok élessége méretenként változik. Jobb egy szigorú, dokumentált mapping-terv.

    Mikor éri meg a ráfordítás?

    Három egyértelmű indikátor mutatja, hogy megéri egy átgondolt High‑DPI ikon-pipeline:

    • A felhasználóid vegyes monitorokkal dolgoznak (laptop + külső) vagy sokan RDP-n keresztül használják.
    • Az alkalmazás hosszú életű és éveken át karbantartásra kerül — a UI-észlelés az elfogadás része.
    • Amúgy is modernizációs lépések előtt állsz (DPI-érzékenység emelése, Controls cseréje, Toolbar-elrendezés felülvizsgálata).

    Ha viszont az app csak egy fix kioskrendszeren fut azonos felbontással, akkor minimalizálhatod a témát: biztosíts egy megfelelő ikonméretet, állítsd be helyesen a DPI-érzékenységet, és kész.

    Fazit: High‑DPI nem kozmetikai részlet, hanem egy renderelési döntés

    VCL-ben az életlen ikonok ritkán izolált hibák; általában a források, a skálázás és a cache láncolatának nem tiszta működésére utalnak. A legrobosztusabb megoldás, ha több felbontásban adod meg az ikonokat és egy központi pipeline-on keresztül (pl. ImageCollection/VirtualImageList vagy egy saját ikonréteg) konzisztensen szolgáltatod őket. Futásidejű skálázás akkor indokolt, ha dinamikus forrásaid vagy összetett szimbólumaid vannak — de csak mesterforrással, DPI-alapú cache-sel és egyértelmű rebuild-szabályokkal.

    Ha konkrét tüneteket tapasztalsz (DPI-váltás tönkreteszi az ikonokat, halo a széleken, hibás méretek RDP után), érdemes a problémát célzottan izolálni és mint kis architekturális elemet kezelni, ahelyett hogy formonként workaroundokat halmoznál. Ha támogatásra van szükséged a hibakeresésben vagy lépésenkénti modernizációban, itt találod a megfelelő belépést: Kapcsolat a Net-Base Software GmbH.

    Ehhez a témához a Timagelist High Dpi és Delphi Vcl Dpi-Awareness is fontos. A cikk ezeket a szempontokat érthetően rendszerezi, és bemutatja, mi számít a mindennapi gyakorlatban.

    Projekt vagy modernizációs terv megbeszélése a Net-Base segítségével.

    Következő lépés

    Ha a téma valós projektté válik, az architektúrát, a meglévő rendszert és az üzemeltetést már korán együtt kell értékelni.

    Nemcsak egyedi kérdésekben támogatunk, hanem akkor is, amikor forráskódrészletekből, örökölt rendszerekkel kapcsolatos témákból vagy portálötletekből robusztus vállalati projektet kell kialakítani.

    • A jelenlegi állapotot, a célállapotot és a műszaki kockázatokat együttesen értékeljük.
    • REST, az adathozzáférés, a portálok és a Rollout nem kerülnek utólagos teendőkként elhalasztásra.
    • Már korán láthatja, melyik út gazdaságilag és üzemeltetési szempontból életképes.

    Bejegyzés megosztása

    Ezt a bejegyzést közvetlenül megosztani

    LinkedIn, X, XING, Facebook, WhatsApp és e-mail azonnal elérhetők. Instagramhoz linket és rövid szöveget közvetlenül előkészítünk.

    E-mail

    Az Instagram egy új lapon nyílik meg. A link és a rövid szöveg előzetesen a vágólapra másolódik.