Nga tema e revistës në praktikën e projektit
Faqe shërbimi dhe teknike të përshtatshme për artikullin
Kush drejton aplikacione VCL në klientët modernë Windows do të ndeshet herët a vonë me të njëjtin simptomë: ikonat duken në 125%/150%/200% të shkallës si të mjegulluara, të prera në skaj ose marrin një kufi gri. Pikërisht këtu tema VCL High-DPI Icons bëhet praktike: jo sepse High‑DPI është e re, por sepse problemet zakonisht shfaqen vetëm në përdorim të përditshëm — në servera terminal, gjatë ndërrimit të dokut të laptopit ose sapo monitorët të kenë DPI të ndryshme.
Çështja kryesore thuajse kurrë nuk është se PNG-ja është prishur, por pipeline-i: nga vjen ikona (Ressource, Datei, SVG, Font), në çfarë Größe ofrohet, si përfundon në TImageList dhe kush kur si e skalon. Në VCL bashkohen disa terma që duhet të dallohen: DPI-Awareness (nëse Windows e skalon aplikacionin apo aplikacioni vetë), Per-Monitor-DPI (çdo monitor mund të jetë ndryshe) dhe ImageList-Strategie (mbajtja e disa Auflösungen ose rasterizimi zur Laufzeit).
Këtë artikull e kemi synuar të mos hapë debate mbi dizajnin e UI-së, por të prezantojë një qasje të pastër dhe të besueshme për operim: skalimi i ikonave në kohë ekzekutimi, por në mënyrë që të mos shndërrohen në përtypje pixelash, të ruajnë kanalet Alpha dhe që ndryshimet e DPI-t të funksionojnë pa pulsim ose me madhësi të gabuara të figurës. Shtohen edhe kurthat, këshillat për debugging dhe një vlerësim i sinqertë se kur ia vlen Mehraufwand-i.
Warum Pixelmatsch entsteht: Skalierungskette in der VCL verstehen
Arsyeja më e përhapur për ikona të paqartë është një Down-/Upscaling i vetëm në kohën e gabuar. Rrjedha klasike në Legacy‑VCL:
- Aplikacioni jep ikonat vetëm në 16×16 ose 24×24.
- Windows ose VCL e skalon në 20×20 / 32×32 / 48×48.
- Skalari përdor një interpolim që për fotot është i pranueshëm, por për grafikën pixel shlyen skajet.
- Shtesë, transparenca (Alpha) shtyhet në një logjikë maske ose konvertohet disa herë.
Bëhet veçanërisht problem kur ndodhin disa shkallë njëra pas tjetrës: për shembull kur ImageList tashmë jep një bitmap të skalosur, dhe Windows për shkak të DPI‑Unaware ose System‑DPI e skalon përsëri. Rezultati: zbutje e dyfishtë.
Një pikë e dytë, që nënvlerësohet në projekte, është momenti i skalimit. Me Per‑Monitor‑DPI (PMv2, pra Per‑Monitor‑DPI‑Awareness v2) DPI‑ja efektive mund të ndryshojë kur një dritare kalon në një monitor tjetër ose kur një klient Remote‑Desktop rregullon DPI‑n dinamikisht. Nëse atëherë një TImageList ose një cache nuk rindërtohet si duhet, papritmas shohim ikona në madhësi të gabuar ose me raster të gabuar.
TImageList unter High-DPI: typische Fallen in echten Anwendungen
Die TImageList ist historisch für kleine Bitmaps gedacht, mit festen Maßen, Indizes und relativ starrer Speicherlogik. Unter High-DPI ergeben sich daraus praxisnahe Fallen:
1) Fest verdrahtete Width/Height
Shumë formularë VCL vendosin ImageList.Width/Height në kohën e dizajnit dhe e lënë ashtu. Në 150% Windows mund të dëshirojë, p.sh., që nga 16×16 të kalojë në 24×24. Nëse lista mbetet në 16×16, ikonat ose do të priten ose do të shkallen në një vend tjetër — të dyja të pafavorshme.
2) PNG-Alpha und Maskenlogik
Varësisht nga Delphi-Version und VCL-Controls landet man schnell in einem Mischbetrieb: PNGs mit Alpha werden intern teils als 32-bit Bitmap gehalten, teils als Mask+Color. Sobald du mehrfach konvertierst (PNG → Bitmap → ImageList → Draw), entstehen graue Halos oder harte Kanten. Der Effekt ist häufig backgroundsensitiv: Auf dunkler Toolbar sieht es schlimmer aus als auf einem hellen Panel.
3) DPI-Wechsel zur Laufzeit: Caches, Handles, OwnerDraw
Disa kontrolle mbajnë në cache paraqitjen e imazhit ose marrin ImageList-Handles në një moment kur DPI ende nuk është përfundimtare. Veçanërisht te Toolbars, TreeViews/ListViews und OwnerDraw-Szenarien, pas ndryshimeve të DPI ndonjëherë shfaqen madhësi imazhi të gabuara ose ikona bosh, derisa të ndodhë një Repaint ose një RecreateWnd.
4) Terminalserver und Remote-Desktop als Realitätstest
Nëse aplikacioni përdoret përmes RDP, ndryshimet e DPI dhe rivendosjet e sesionit nuk janë të rralla. Pikërisht atje një strategji jo e qëndrueshme për ImageList do të dështojë: përdoruesi sheh pas rikonektimit ikona të paqarta ose shiritë veglash të skaluar gabim, edhe pse lokalisht gjithçka ishte në rregull.
Sauberer Ansatz: Mehrere Auflösungen bereitstellen statt brutales Upscaling
Vendimi më i rëndësishëm është konceptual: Dëshiron të rritësh në kohë ekzekutimi ikonat nga një grafikë bazë e vetme (p.sh. 16×16 → 32×32), oder ofron të shumta rezolucione native dhe zgjedh sipas DPI atë të përshtatshmen?
Në praktikë pothuajse gjithmonë fiton opsioni «mehrere Auflösungen». Upscaling mund të bëhet nëse burimi është vektorial (SVG, Icon-Font) ose nëse ke nevojë vetëm për faktorë të moderuar. Sa herë që rritet shumë nga një imazh raster i vogël, humbet cilësia e skajeve, dhe këtë e vëren menjëherë në ekranet moderne.
In der VCL-Welt sind für diesen Ansatz heute zwei Bausteine relevant:
- TImageCollection: Container për imazhe në disa madhësi/variantë.
- TVirtualImageList: krijon prej tyre në kohë ekzekutimi një ImageList me madhësinë aktualisht të nevojshme dhe reagon ndaj ndryshimeve të DPI.
Kjo nuk do të zgjidhë të gjitha problemet, por e vendos çështjen në vendin e duhur: ti definon burimet e imazheve qartë, dhe skalimi/zgjedhja kryhet në mënyrë konsistente.
VCL High-DPI Icons zur Laufzeit skalieren: Wann es sinnvoll ist (und wann nicht)
Ka arsye të legjitime për të skaluar ikonat në kohë ekzekutimi:
- Ngarkon ikonat në mënyrë dinamike (p.sh. nga një dosje plugin-esh, pako branding të klientit, pako konfigurimi).
- Dëshiron një pipeline uniforme për burime të ndryshme (ICO, PNG, SVG) dhe nuk dëshiron të përfshish të gjitha variantet në kohën e build-it.
- Gjeneron ikonat në mënyrë programatike (status-badges, overlays, ikona të përbëra).
Nuk është e arsyeshme skalimi në kohë të ekzekutimit nëse në të vërtetë ke vetëm ikona klasike të një Toolbar nga një set fiks. Atëherë rruga më pak e kërkuar për mirëmbajtje është: shpërndaje me rregull disa rezolucione dhe lejo VCL të zgjedhë.
Nëse bën skalim në kohë të ekzekutimit, bëje atë me rregulla të qarta:
- Kurrë mos skalo përsëri nga një bitmap që është tashmë i skaluar. Gjithmonë nis nga një burim master (idealja vektorial ose me rezolucion të lartë).
- Cache për madhësinë e synuar dhe DPI, përndryshe skalon në çdo Paint përsëri — kjo konsumon CPU dhe mund të shkaktojë ngecje.
- Ruaj alpha: minimizo konvertimet, vendos në 32-bit RGBA, mos rasterizo sfondin.
Arkitekturë pragmatike: pipeline e ikonave si një komponent i pavarur
Në aplikacione më të mëdha ia vlen që çështjen ta mos e shpërndash kudo, por të ndërtohesh një pipeline të vogël. Nuk duhet të jetë një framework — më shumë një fushë përgjegjësie e qartë:
- Burimi i ikonave: Nga vijnë asetet master (burime, skedarë, bazë të dhënash, API)?
- Rasterizer/Scaler: Si krijohet nga master në madhësitë e synuara (interpolim, në rast nevoje render SVG)?
- Cache: Çelësi (Icon-ID, pikselët e synuar, DPI, Theme) dhe cikli i jetës (invalidim tek ndryshimi i DPI, ndryshimi i Theme, ndryshimi i paketës).
- Consumer-Adapter: Si hyn rezultati në strukturat VCL (TImageList/TVirtualImageList, OwnerDraw, PaintBox)?
Avantazhi: Mund të debug-osh bugs të DPI të riprodhueshme në një vend, në vend që të kërkosh në 40 Forms ku „përsëri po skalohen“.
Trajtimi korrekt i ndryshimit të DPI: Ngjarjet, Rebuild, Repaint
Nën Windows ndryshimet e DPI janë një cikël jete i veçantë. Në VCL ka, në varësi të versionit dhe DPI-awareness, disa ngjarje/mekanizma, por parimi bazë mbetet:
- Nëse DPI e dritares ndryshon, burimet bazë imazhesh që duhet të jenë pixel-saktë duhet të rikrijohen.
- Nëse mbush ImageLists në mënyrë dinamike, shpesh nuk mjafton një thjesht Invalidate — të duhet një Rebuild i imazheve në madhësinë e re të synuar.
Një model praktik është: te ndryshimi i DPI (p.sh. Form-Scale/ndryshim monitori) të invalidosh cache e ikonave për atë DPI dhe të rindërtohesh ImageLists e prekur. E rëndësishme është të mos skalohet brenda Paint-Events, por në një bllok update të kontrolluar (Toolbar.BeginUpdate/EndUpdate, fik ListView-Redraw, pastaj ndiz përsëri). Kështu shmang fluktuacionet dhe gjendjet gjysmake të UI.
Pse TImageList shpesh bëhet e paqartë: interpolim, rrumbullakësim DPI, skaje
Nëse njëherë kupton se problemi nuk është thjesht DPI, por interpolim plus rrumbullakësim, shumë efekte shpjegohen:
- DPI-Rrotullimi: 125a0% nuk është një dyfishues i pastër. Nga 16 px bëhen 20 px (16 * 1,25). Nga 24 px bëhen 30 px. Këto janë numra të çrregullt që vështirësojnë skajet e pixeleve.
- Filteri i resampling: Bilinear/Bicubic i zbut skajet. Kjo është për fotografi në rregull, por për ikona shpesh jo.
- Efektet subpixel: Windows mund të përdorë ose jo Subpixel-Antialiasing, në varësi të rrugës së renderimit. Tek ikonat dëshiron skaje të kontrolluara dhe sa më pak shtresa filtrimi të shumëfishta.
Nëse ke ikona raster, në shumë ekipe është praktikë e zakonshme të ofrohen PNG të veçanta për secilën madhësi të synuar (16/20/24/32/40/48). Duket shumë, por shpesh është më pak punë sesa të debug-osh për vite me radhë pse në këtë monitor duket çuditshëm.
Debugging: Bëj të riprodhueshëm Pixelmatsch në vend që t9i rregullosh sipas intuit9s
Gabimet High-DPI shpesh duken të rastësishme. Me disa kontrolle bëhen deterministikë:
1) Regjistro DPI dhe madhësitë e ImageList gjatë kohës së ekzekutimit
Regjistro te fillimi dhe te çdo ndryshim DPI: CurrentPPI i form-it, Screen.PixelsPerInch (Vërejtje: kjo mund të jetë DPI i sistemit), si dhe ImageList.Width/Height të listave të prekura. Nëse pas një ndërrimi monitori ende sheh 16d716, ndërkohë që priste 32, shkaku është i qartë: mungon rebuild ose ai vjen tepër vonë.
2) Zmadho ikonat në mënyrë të dukshme
Një test i shpejtë është të vendosësh përkohësisht ikonat e toolbar-it në 48 px. Skalimi i dobët do të bëhet menjëherë i dukshëm. Pipelines e mira qëndrojnë të mprehta edhe në 48 px, sepse rasterizohen nga një burim i përshtatshëm.
3) Testo ndryshimet e theme dhe sfondit
Halot në skaj shpesh janë probleme me Alpha/Premultiply. Testo në dritë/të errët dhe në zona me gradient ngjyrash. Nëse skaji duket ndryshe në varësi të sfondit, trajtimi i transparencës nuk është i saktë.
4) Remote Desktop / Ndërrimi i monitorit si skript testi
Krijo një skript të shkurtër testimi për QS: nis aplikacionin në Monitorin A (100%), lëviz dritaren në Monitorin B (150%), kthehu, pastaj rilidh RDP. Nëse kjo qëndron e qëndrueshme, shumë probleme të klientëve janë zhdukur.
Migrimi në aplikacionet ekzistuese: Hapat një nga një në vend të Big Bang
Në aplikacionet VCL të zhvilluara me kalimin e kohës, logjika e ikonave shpesh ndodhet në shumë vende: menyja, toolbar-et, ActionLists, TreeViews, shenjat e statusit. Një rindërtim total sjell rrezik. Ka provuar vete një qasje etapë-pas-etape:
- Inventar: Cilat ImageList ekzistojnë? Cilat kontrolle i përdorin ato? Çfarë madhësish priten?
- Prioritizim: Fillimisht zonat më të dukshme (toolbar-i kryesor, navigimi, menutë kontekstuale).
- Burim i unifikuar: Centralizo ikonat (ImageCollection ose një loader i vet) në vend që të ngarkosh skedarë të ndarë për çdo formë.
- Test i ndryshimit të DPI: Nga modulet e para të riparuara bëni teste të ndryshimit të DPI me përpikëri.
Wichtig: Wenn du parallel alte und neue Pipeline betreibst, dokumentiere klare Regeln. Sonst entsteht eine Mischlandschaft, in der manche Icons scharf sind und andere sichtbar të zbehta wirken.
Performance und Speicher: Laufzeit-Skalierung ohne Nebenwirkungen
Skalierung kostet CPU und Speicher. In einer Business-Software fällt das selten im Leerlauf auf, aber beim Verschieben eines Fensters auf einen neuen Monitor oder beim Start mit vielen Forms kann es ruckeln. Drei praktische Leitplanken:
- Cache-Größe begrenzen: Nicht jede Zwischenstufe ewig halten. Wenn du nur 100% und 150% brauchst, cache auch nur diese.
- Lazy Build: Icons erst rastern, wenn der Screen sie wirklich braucht. Bei großen Menüs spart das Startzeit.
- Batch-Rebuild: Beim DPI-Wechsel nicht jedes Control einzeln triggern. Ein zentraler Rebuild verhindert redundantes Skalieren.
Wenn du mit TVirtualImageList arbeitest, ist vieles davon bereits als Konzept enthalten, aber du musst trotzdem darauf achten, nicht zusätzlich noch eigene Skalierung oben drauf zu bauen.
Fallback-Strategien: Was tun, wenn nicht alle Icon-Größen vorliegen?
In der Realität hast du nicht immer alle Assets in allen Größen. Dann brauchst du eine klare Fallback-Strategie, um zufällige Ergebnisse zu vermeiden:
- Prefer Downscale: Lieber von 64 px auf 32 px runter als von 16 px auf 32 px hoch.
- Definiere Stufen: Lege fest, welche Zielgrößen du wirklich supportest (z. B. 16/20/24/32/40/48) und mappe DPI sauber darauf.
- Transparenz testen: Bei Fallbacks besonders auf Alpha achten — genau dort entstehen Halos.
Ein typischer Fehler ist, irgendeine nächste Größe zu nehmen. Dadurch variiert die wahrgenommene Schärfe je nach Icon. Besser ist ein harter, dokumentierter Mapping-Plan.
Wann lohnt sich der Aufwand wirklich?
Es gibt drei klare Indikatoren, dass sich eine saubere High-DPI-Icon-Pipeline lohnt:
- Deine Nutzer arbeiten mit gemischten Monitoren (Laptop + extern) oder viel per RDP.
- Die Anwendung ist langlebig und wird über Jahre gepflegt — UI-Wahrnehmung ist Teil der Akzeptanz.
- Du hast ohnehin Modernisierungsschritte vor dir (DPI-Awareness anheben, Controls tauschen, Toolbar-Layout überarbeiten).
Wenn die App dagegen nur auf einem festen Kiosk-System mit identischer Auflösung läuft, kann man das Thema minimal halten: eine passende Icon-Größe liefern, DPI-Awareness sauber setzen, fertig.
Fazit: High-DPI ist kein kosmetisches Detail, sondern eine Rendering-Entscheidung
Unscharfe Icons sind in der VCL selten ein isolierter Fehler, sondern ein Hinweis auf eine unsaubere Kette aus Quellen, Skalierung und Caching. Der robusteste Weg ist, Icons in mehreren Auflösungen bereitzustellen und sie über eine zentrale Pipeline (z. B. ImageCollection/VirtualImageList oder eine eigene Icon-Schicht) konsistent zu liefern. Laufzeit-Skalierung ist dann sinnvoll, wenn du dynamische Quellen oder zusammengesetzte Symbole hast, aber nur mit Master-Quelle, DPI-basiertem Cache und klaren Rebuild-Regeln.
Wenn du konkrete Symptome hast (DPI-Wechsel macht Icons kaputt, Halos am Rand, falsche Größen nach RDP), lohnt es sich, das Thema gezielt zu isolieren und als kleinen Architekturbaustein zu behandeln, statt pro Form Workarounds zu stapeln. Wenn du dabei Unterstützung beim Debugging oder bei einer schrittweisen Modernisierung brauchst, findest du hier den passenden Einstieg: Kontakt zur Net-Base Software GmbH.
Për këtë temë janë të rëndësishme edhe Timagelist High Dpi dhe Delphi Vcl Dpi-Awareness. Ky artikull i vendos këto aspekte në kontekst në mënyrë të qartë dhe tregon çfarë ka rëndësi në praktikën e përditshme.
Diskutoni projektin ose iniciativën e modernizimit me Net-Base.
Hapi tjetër
Kur nga një temë lind një projekt real, arkitektura, sistemi ekzistues dhe operimi duhet të vlerësohen së bashku që në fillim.
Ne nuk mbështesim vetëm në çështje të veçanta, por edhe kur nga fragmente të kodit burimor, temat legacy ose idetë për portale duhet të zhvillohen në një projekt korporativ të qëndrueshëm.
- Gjendja ekzistuese, imazhi i synuar dhe rreziqet teknike vlerësohen së bashku.
- REST, qasja në të dhëna, portalet dhe implementimi nuk shtyhen si pasojë e mëvonshme.
- Ju e shihni herët se cila rrugë është e qëndrueshme ekonomikisht dhe operativisht.