Net-Base Dergi

18.08.2026

VCL High-DPI: Çalışma zamanında ikonları ölçeklendirme ve TImageList'te piksel bulanıklığını önleme

VCL'de High-DPI yalnızca bir onay kutusu değildir; ImageList yapılandırması, DPI değişim olayları ve temiz renderlemeden oluşan bir zincirdir. Bu uygulamalı yazı, simgeleri çalışma zamanında nasıl ölçeklendireceğinizi, artefaktlardan nasıl kaçınacağınızı ve tipik TImageList tuzaklarını yeniden üretilebilir şekilde nasıl hata ayıklayacağınızı gösterir.

18.08.2026

Dergi konusundan proje pratiğine

İçeriğe Uygun Hizmet ve Teknik Sayfalar

VCL uygulamalarını modern Windows-istemcilerde çalıştıranlar er ya da geç aynı semptomla karşılaşır: %125/%150/%200 gibi ölçeklerde ikonlar bulanık, tüylenmiş veya gri kenarlı görünür. Tam da bu noktada VCL High-DPI ikonları pratikleşir: High-DPI’nin yeni olmasından değil, sorunların çoğunlukla günlük kullanımda — terminal sunucularında, dizüstü bilgisayarın dock değişiminde veya monitör başına farklı DPI’lar olduğunda — ortaya çıkmasındandır.

Temel sorun neredeyse hiç „PNG bozuk“ değildir, aksine boru hattındadır: ikon nereden geliyor (kaynak, dosya, SVG, font), hangi boyutta sağlanıyor, nasıl TImageList‚e giriyor ve kim ne zaman nasıl ölçeklendiriyor. VCL’de ayrıca ayrılması gereken birkaç kavram bir araya gelir: DPI-Awareness (Windows uygulamayı mı yoksa uygulamanın kendini mi ölçeklediği), Per-Monitor-DPI (her monitör farklı olabilir) ve ImageList-Strategie (birden fazla çözünürlük bulundurmak mı yoksa çalışma zamanında rasterize etmek mi).

Bu yazıda kasıtlı olarak UI tasarım tartışmalarına girilmiyor; amaç temiz, işletme açısından güvenli bir yaklaşım: ikonları çalışma zamanında ölçeklemek ama öyle ki piksel çorbası olmasın, alfa kanalları sağlam kalsın ve DPI değişimleri titremeden veya yanlış görüntü boyutları olmadan çalışsın. Buna ek olarak tuzaklar, hata ayıklama notları ve ekstra emeğin ne zaman haklı olduğunu gösteren dürüst bir değerlendirme yer alıyor.

Neden piksel çorbası oluşur: VCL’de ölçeklendirme zincirini anlamak

Grafik zur Icon-Skalierung: Master-Icon wird in mehrere Zielgrf6dfen gerastert, doppelte Skalierung ffchrt zu Unsche4rfe
Tek bir master kaynaktan yapılan bir kerelik ölçeklendirme kontrol edilebilir — çift kat yeniden örnekleme adımları hızla gözle görülür bulanıklığa yol açar.

Bulanık ikonların en sık nedeni, yanlış zamanda yapılan bir tek seferlik küçültme/büyütme‚dir. Legacy-VCL’deki klasik akış:

  • Uygulama ikonları yalnızca 16×16 veya 24×24 sağlar.
  • Windows veya VCL 20×20 / 32×32 / 48×48’e ölçekler.
  • Skaler, fotoğraflar için kabul edilebilir bir enterpolasyon kullanır, ancak piksel grafikte kenarları bulanıklaştırır.
  • Ayrıca transparans (alfa) bir maske mantığına sıkıştırılır veya birden fazla kez dönüştürülür.

Daha da kötüleşir, eğer birden fazla ölçek ard arda uygulanıyorsa: örneğin ImageList zaten ölçeklenmiş bir bitmap sağlıyorsa ve Windows DPI-unaware veya sistem DPI nedeniyle üzerine tekrar ölçeklendiriyorsa. Sonuç: çift kat bulanıklaştırma.

Projelerde genellikle küçümsenen ikinci nokta ölçeklendirme zamanı‚dır. Per-Monitor-DPI (PMv2, yani Per-Monitor-DPI-Awareness v2) durumunda efektif DPI, bir pencere monitör değiştirdiğinde veya bir Remote-Desktop istemcisi DPI’yi dinamik olarak ayarladığında değişebilir. Bu durumda bir TImageList veya bir önbellek doğru şekilde yeniden oluşturulmazsa, aniden ikonlar yanlış boyutta veya yanlış raster ile görünür.

TImageList High-DPI altında: gerçek uygulamalarda tipik tuzaklar

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

Viele VCL-Formulare setzen ImageList.Width/Height zur Designzeit und lassen es dabei. Bei 150% möchte Windows aber z. B. aus 16×16 eher 24×24 machen. Wenn die Liste auf 16×16 bleibt, wird entweder geclippt oder an anderer Stelle skaliert — beides unschön.

2) PNG-Alpha und Maskenlogik

Je nach 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

Einige Controls cachen die Bilddarstellung oder übernehmen ImageList-Handles zu einem Zeitpunkt, wo die DPI noch nicht final ist. Besonders bei Toolbars, TreeViews/ListViews und OwnerDraw-Szenarien sieht man nach DPI-Wechseln sporadisch falsche Bildgrößen oder leere Icons, bis ein Repaint oder ein RecreateWnd passiert.

4) Terminalserver und Remote-Desktop als Realitetstest

Wenn die App über RDP genutzt wird, sind DPI-Wechsel und Session-Reconnects nicht exotisch. Genau dort fliegt dir eine unrobuste ImageList-Strategie um die Ohren: Der Benutzer sieht nach dem Reconnect verwaschene Icons oder falsch skalierte Symbolleisten, obwohl lokal alles ok war.

Sauberer Ansatz: Mehrere Auflösungen bereitstellen statt brutales Upscaling

Die wichtigste Entscheidung ist konzeptionell: Willst du Icons zur Laufzeit aus einer einzigen Basisgrafik hochskalieren (z. B. 16×16 → 32×32), oder stellst du mehrere native Auflösungen bereit und wählst je nach DPI die passende?

In der Praxis gewinnt fast immer die mehrere Auflösungen-Strategie. Upscaling kann man machen, wenn die Quelle vektorbasiert ist (SVG, Icon-Font) oder wenn du wirklich nur moderate Faktoren brauchst. Sobald du aus einem kleinen Rasterbild stark hochskalierst, verlierst du Kantenqualität, und das siehst du auf modernen Displays sofort.

In der VCL-Welt sind für diesen Ansatz heute zwei Bausteine relevant:

  • TImageCollection: Container für Bilder in mehreren Größen/Varianten.
  • TVirtualImageList: erzeugt daraus zur Laufzeit eine ImageList in der aktuell benötigten Größe und reagiert auf DPI-Änderungen.

Das nimmt dir nicht alle Probleme ab, aber es verschiebt das Problem an die richtige Stelle: Du definierst Bildquellen sauber, und die Skalierung/Selektion passiert konsistent.

VCL High-DPI Icons zur Laufzeit skalieren: Wann es sinnvoll ist (und wann nicht)

Es gibt legitime Gründe, Icons zur Laufzeit zu skalieren:

  • Du lädst Icons dynamisch (z. B. aus einem Plugin-Ordner, kundenspezifische Branding-Pakete, Konfigurationspakete).
  • Du willst eine einheitliche Pipeline für verschiedene Quellen (ICO, PNG, SVG) und möchtest nicht alle Varianten zur Build-Zeit binden.
  • Du erzeugst Icons programmgesteuert (Status-Badges, Overlays, zusammengesetzte Symbole).

Laufzeit-Ölçekleme sadece sabit bir setten klasik araç çubuğu simgeleri kullanıyorsanız mantıklı değildir. Bu durumda en az bakım gerektiren yol: birden fazla çözünürlüğü düzgünce teslim etmek ve VCL’nin seçim yapmasına izin vermektir.

Eğer Laufzeit-Skalierung yapıyorsanız, bunu şu net kurallarla yapın:

  • Asla zaten ölçeklenmiş bir bitmap’ten yeniden ölçekleme. Her zaman bir Master kaynağından başla (idealde vektör tabanlı veya yüksek çözünürlüklü).
  • Hedef boyut ve DPI başına cache, aksi halde her Paint’te tekrar ölçeklersiniz — bu CPU tüketir ve takılmalara yol açabilir.
  • Alfa kanalı koru: Dönüştürmeleri en aza indir, 32-bit RGBA kullan, arka planı rasterleştirme.

Pragmatische Architektur: Icon-Pipeline als eigener Baustein

Daha büyük uygulamalarda konuyu her yere yaymak yerine küçük bir pipeline kurmak faydalıdır. Bu bir framework olmak zorunda değildir — daha çok tanımlı bir sorumluluk alanı:

  • Icon-Quelle: Ana varlıklar nereden geliyor (Ressourcen, Dateien, Datenbank, API)?
  • Rasterizer/Scaler: Ana kaynaktan hedef boyut nasıl üretiliyor (Interpolation, gerekirse SVG-Render)?
  • Cache: Anahtar (Icon-ID, hedef piksel, DPI, Theme) ve yaşam döngüsü (DPI-Wechsel, Theme-Wechsel, Paketwechsel durumlarında invalidieren).
  • Consumer-Adapter: Sonuç nasıl VCL yapısına gelir (TImageList/TVirtualImageList, OwnerDraw, PaintBox)?

Avantaj: DPI hatalarını tek bir yerde tekrarlanabilir şekilde debug edebilirsiniz; 40 Form arasında „nerede tekrar ölçekleniyor“ diye aramak zorunda kalmazsınız.

DPI-Wechsel korrekt behandeln: Ereignisse, Rebuild, Repaint

Notebook mit zwei Monitoren unterschiedlicher DPI, Fensterwechsel zeigt unterschiedliche Icon-Grf6dfen in einer Desktop-App
Per-Monitor-DPI gerçeklik testidir: Monitör değişiminde Icon-Pipeline yeniden rasterlenmeli, sadece yeniden çizilmemelidir.

Windows altında DPI-Wechsel kendi yaşam döngüsüne sahiptir. VCL’de sürüme ve DPI-Awareness durumuna göre birden çok olay/mekanizma bulunur, ama temel ilke aynıdır:

  • Pencerenin DPI’sı değiştiğinde, piksel-hassas olması gereken görüntü tabanlı kaynaklar yeniden sağlanmalıdır.
  • ImageLists’i dinamik dolduruyorsanız, yalnızca bir Invalidate genellikle yeterli değildir — yeni hedef boyutta resimlerin Rebuild‚ine ihtiyacınız vardır.

Pratik bir desen: DPI değişiminde (ör. Form-Scale/Monitorwechsel) o DPI için Icon-Cache’i invalidierst ve etkilenen ImageList’leri yeniden oluşturursun. Önemli olan, ölçeklemeyi Paint olayları içinde yapmak değil, kontrollü bir güncelleme bloğunda gerçekleştirmektir (Toolbar.BeginUpdate/EndUpdate, ListView-Redraw kapat, sonra tekrar aç). Böylece titremeyi ve yarım kalmış UI durumlarını önlersiniz.

Warum TImageList so oft unscharf wird: Interpolation, DPI-Rundung, Kanten

Bir kez DPI’nın sorun olmadığını, esas problemin interpolasyon artı yuvarlama olduğunu anlarsanız, birçok etki açıklanabilir:

  • DPI-Rundung: 125a0% ist kein sauberer Verdoppler. Aus 16 px werden 20 px (16 * 1,25). Aus 24 px werden 30 px. Das sind krumme Zahlen, die Pixelkanten erschweren.
  • Resampling-Filter: Bilinear/Bicubic macht Kanten weicher. Das ist für Fotos in der Regel akzeptabel, für Icons oft nicht.
  • Subpixel-Effekte: Windows kann je nach Renderpfad Subpixel-Antialiasing nutzen oder nicht. Bei Icons willst du kontrollierte Kanten und möglichst keine mehrfachen Filterstufen.

Wenn du Raster-Icons hast, ist es in vielen Teams gängige Praxis, pro Zielgröße eigene PNGs zu liefern (16/20/24/32/40/48). Klingt nach viel, ist aber oft weniger Aufwand als jahrelang „warum sieht das auf diesem Monitor komisch aus“ zu debuggen.

Debugging: Pixelmatsch reproduzierbar machen statt nach Bauchgefühl zu fixen

Arbeitsplatz mit Debug-Notizen für Icon-Skalierung und Hintergrundtests zur Alpha-Kante
Gute DPI-Debugging-Routinen testen Größen, Hintergründe und Rebuild-Zeitpunkte — nicht nur den ersten Screenshot.

High-DPI-Bugs wirken oft zufällig. Mit ein paar Checks werden sie deterministisch:

1) DPI und ImageList-Größen zur Laufzeit loggen

Logge bei Start und bei DPI-Wechsel: CurrentPPI des Forms, Screen.PixelsPerInch (Achtung: das kann System-DPI sein), sowie ImageList.Width/Height der betroffenen Listen. Wenn du nach einem Monitorwechsel noch 16 siehst, obwohl du 32 erwartest, ist die Ursache klar: Rebuild fehlt oder kommt zu spät.

2) Icons sichtbar vergrößern

Ein schneller Test ist, die Toolbar-Icons temporär auf 48 px zu setzen. Schlechte Skalierung springt dann sofort ins Auge. Gute Pipelines bleiben auch bei 48 px scharf, weil sie aus einer passenden Quelle rastern.

3) Theme- und Hintergrundwechsel testen

Halos am Rand sind oft Alpha-/Premultiply-Probleme. Teste auf hell/dunkel und auf Flächen mit Farbverlauf. Wenn die Kante je nach Hintergrund anders aussieht, stimmt die Transparenzbehandlung nicht.

4) Remote Desktop / Monitorwechsel als Testskript

Erstelle ein kurzes Testskript für die QS: App starten auf Monitor A (100a0%), Fenster auf Monitor B (150a0%), zurück, dann RDP reconnect. Wenn das stabil ist, sind viele Kundenprobleme bereits erschlagen.

Migration in bestehenden Anwendungen: Schrittweise statt Big Bang

In gewachsenen Delphi-VCL-Anwendungen steckt die Icon-Logik oft an vielen Stellen: Menüs, Toolbars, ActionLists, TreeViews, Statusanzeigen. Ein Big-Bang-Umbau bringt Risiko. Bewährt hat sich ein schrittweises Vorgehen:

  • Inventur: Welche ImageLists gibt es? Welche Controls nutzen sie? Welche Größen werden erwartet?
  • Priorisieren: Zuerst die prominentesten Flächen (Haupttoolbar, Navigation, Kontextmenüs).
  • Einheitliche Quelle: Icons zentralisieren (ImageCollection oder eigener Loader), statt pro Form Einzeldateien zu laden.
  • DPI-Wechsel testen: Ab dem ersten umgebauten Modul konsequent DPI-Wechsel-Tests fahren.

Önemli: Eğer eski ve yeni Pipeline9i paralel işletiyorsan, net kurallar belgeleyin. Aksi takdirde bazı ikonlar keskin olurken diğerleri gözle görülür şekilde tutarsız görünebilir.

Performans ve Bellek: Çalışma Zamanı Ölçeklendirmesi Yan Etkisi Olmadan

Ölçeklendirme CPU ve bellek maliyeti getirir. Bir iş yazılımında bu nadiren boşta fark edilir, ancak pencereyi yeni monit fcre taşırken veya çok sayıda Form ile başlatırken takılma olabilir. Üç pratik kılavuz hattı:

  • Önbellek boyutunu sınırlayın: Her ara kademeyi sonsuza dek tutmayın. Sadece %100 ve %150 gerekiyorsa, sadece bunları cacheleyin.
  • Lazy Build: İkonları ekran gerçekten ihtiyaç duyduğunda rasterle. Büyük menülerde bu başlatma süresinden tasarruf sağlar.
  • Batch-Rebuild: DPI değişiminde her kontrolü tek tek tetiklemeyin. Merkezi bir rebuild gereksiz tekrar ölçeklenmeyi engeller.

TVirtualImageList ile çalışıyorsan, bunun çoğu kavramsal olarak zaten yerleşiktir ancak yine de üzerine ekstra kendi ölçeklemene izin vermemeye dikkat etmelisin.

Fallback-Stratejileri: Tüm ikon boyutları yoksa ne yapmalı?

Gerçekte tüm asset9leri her boyutta elinde bulundurmazsın. Bu durumda rastgele sonuçlar elde etmemek için net bir fallback stratejisine ihtiyaç vardır:

  • Aşağı ölçeklemeyi tercih et: 64 px9den 32 px9ye küçültmek, 16 px9den 32 px9ye büyütmekten daha iyidir.
  • Aşamaları tanımla: Gerçekte hangi hedef boyutları desteklediğini belirle (örn. 16/20/24/32/40/48) ve DPI9yı buna temiz şekilde eşle.
  • Şeffaflığı test et: Fallbacklerde özellikle alfa kanalına dikkat et; tam da orada halo9lar oluşur.

Tipik bir hata, herhangi bir sonraki boyutu rastgele almak9tır. Bu, algılanan keskinliğin ikona göre değişmesine neden olur. Daha iyi olanı, sertçe tanımlanmış ve belgelenmiş bir eşleme planıdır.

Bu çabaya gerçekten ne zaman değer?

Düzgün bir High-DPI ikon pipeline9ının gerekli olduğunu gösteren üç net belirteç vardır:

  • Kullanıcıların karışık monitörlerle çalışması (dizüstü + harici) veya sıkça RDP kullanması.
  • Uygulamanın uzun ömürlü olması ve yıllarca bakımının yapılması; UI algısı kabulün bir parçasıdır.
  • Zaten modernizasyon adımların varsa (DPI farkındalığını yükseltme, kontrolleri değiştirme, araç çubuğu düzenini gözden geçirme).

Eğer uygulama tek bir sabit kiosk sisteminde ve her zaman aynı çözünürlükte çalışıyorsa, konuyu minimal tutmak mümkündür: uygun bir ikon boyutu sağla, DPI-farkındalığını doğru ayarla, iş biter.

Sonuç: High-DPI kozmetik bir detay değil, bir render kararıdır

VCL9deki bulanık ikonlar nadiren izole bir hata olur; genellikle kaynaklar, ölçekleme ve caching9den oluşan temiz olmayan bir zincirin işaretidir. En sağlam yol, ikonları birden fazla çözünürlükte sunmak ve bunları merkezî bir pipeline (ör. ImageCollection/VirtualImageList veya kendi ikon katmanın) üzerinden tutarlı şekilde teslim etmektir. Çalışma zamanı ölçeklendirmesi, dinamik kaynakların veya bileşik sembollerin olduğu durumlarda anlamlıdır; ancak yalnızca bir master kaynak, DPI tabanlı bir cache ve net rebuild kurallarıyla birlikte.

Somut semptomların varsa (DPI değişimi ikonları bozuyor, kenarlarda halo9lar, RDP sonrası yanlış boyutlar), konuyu hedefli olarak izole etmek ve küçük bir mimari bileşen olarak ele almak genellikle Form başına geçici çözümler yığınlamak yerine daha etkilidir. Bu süreçte debug veya kademeli modernizasyon desteğine ihtiyacın olursa, uygun başlangıcı burada bulabilirsin: Kontakt zur Net-Base Software GmbH.

Bu konu bakımından Timagelist High Dpi ve Delphi Vcl Dpi-Awareness da önem taşır. Yazı bu hususları anlaşılır şekilde ele alır ve günlük kullanımda nelere dikkat edilmesi gerektiğini gösterir.

Proje veya modernizasyon girişimini Net-Base ile görüşün.

Sonraki adım

Konu gerçek bir projeye dönüştüğünde, mimari, mevcut sistemler ve işletme erken dönemde birlikte değerlendirilmelidir.

Bireysel sorularda destek vermekle kalmıyoruz; kaynak kodu parçacıklarından, legacy konularından veya portal fikirlerinden sağlam bir kurumsal projeye dönüşene kadar da destek veriyoruz.

  • Mevcut durum, hedef durum ve teknik riskler birlikte değerlendirilir.
  • REST, veri erişimi, portallar ve Rollout daha sonra ortaya çıkan sonuçlar olarak ertelenmez.
  • Hangi yolun ekonomik ve işletme açısından sürdürülebilir olduğunu erken görürsünüz.

Gönderiyi paylaş

Bu gönderiyi doğrudan paylaş

LinkedIn, X, XING, Facebook, WhatsApp ve e-posta hemen kullanılabilir. Instagram için bağlantıyı ve kısa metni doğrudan hazırlıyoruz.

E-posta

Instagram yeni bir sekmede açılır. Bağlantı ve kısa metin önceden panoya kopyalanır.