![]() |
Wie skaliert man am besten die Grafiken einer TPngImageList?
Liste der Anhänge anzeigen (Anzahl: 1)
Um hohe Display-Auflösungen zu unterstützen, habe ich meine Anwendungen bereits mit dem korrekten Manifest versehen und in Kleinstarbeit alles so angepasst, dass alle Komponenten, Abstände, usw. auch bei 125% … 200% gut aussehen.
Das einzige verbleibende Problem sind die Menü-Grafiken, die leider nicht skaliert werden. Ich verwende (historisch bedingt) 16px PNG-Grafiken (mit Alpha-Channel), die in einer TPngImageList gebündelt sind und Menüs, Schaltflächen, etc. zugewiesen werden. http://www.delphipraxis.net/attachme...1&d=1461677064 Alle Grafiken neu designen kommt aktuell aufgrund der größeren Menge leider nicht in Frage. Ich habe keine Möglichkeit gefunden, die Menüs zu überreden, die Icons zu strecken. Aber selbst wenn das gehen würde, wäre die Qualität der Vergrößerung vermutlich eher bescheiden. Daher die Frage: Wie lässt sich eine TPngImageList mit samt aller enthaltenen Grafiken am besten hochskalieren? Ich versuche es aktuell so:
Delphi-Quellcode:
pilTemp := TPngImageList.Create(nil);
try pilTemp.AddImages(pil16); pil16.SetSize(24, 24); //dadurch gehen alle Grafiken verloren; 24 ist nur ein fixes Beispiel for i := 0 to pilTemp.Count-1 do begin png := pilTemp.PngImages[i].PngImage; SmoothResize(png, 24, 24); pil16.AddPng(png); end; finally pilTemp.Free; end;
Delphi-Quellcode:
ist dabei eine Funktion von hier:
SmoothResize
![]()
Delphi-Quellcode:
Das funktioniert auch bis zu einem gewissen Grad ganz gut. Allerdings hat die Funktion Probleme damit, wenn bei der Ursprungsgrafik Pixel direkt am Rand liegen. Diese werden nach der Vergrößerung leider nicht so weich wie die anderen Bildteile, sondern sehen eher abgeschnitten aus.
procedure SmoothResize(apng: TPNGObject; newWidth, newHeight: Integer);
var xscale, yscale : Single; sfrom_y, sfrom_x : Single; ifrom_y, ifrom_x : Integer; to_y, to_x : Integer; weight_x, weight_y : array[0..1] of Single; weight : Single; new_red, new_green : Integer; new_blue, new_alpha : Integer; new_colortype : Integer; total_red, total_green : Single; total_blue, total_alpha: Single; isAlpha : Boolean; ix, iy : Integer; bTmp : TPNGObject; sli, slo : pRGBLine; ali, alo: pbytearray; begin if not (apng.Header.ColorType in [COLOR_RGBALPHA, COLOR_RGB]) then raise Exception.Create('Only COLOR_RGBALPHA and COLOR_RGB formats are supported'); isAlpha := apng.Header.ColorType in [COLOR_RGBALPHA]; if isAlpha then new_colortype := COLOR_RGBALPHA else new_colortype := COLOR_RGB; bTmp := TPNGObject.CreateBlank(new_colortype, 8, newWidth, newHeight); xscale := bTmp.Width / (apng.Width-1); yscale := bTmp.Height / (apng.Height-1); for to_y := 0 to bTmp.Height-1 do begin sfrom_y := to_y / yscale; ifrom_y := Trunc(sfrom_y); weight_y[1] := sfrom_y - ifrom_y; weight_y[0] := 1 - weight_y[1]; for to_x := 0 to bTmp.Width-1 do begin sfrom_x := to_x / xscale; ifrom_x := Trunc(sfrom_x); weight_x[1] := sfrom_x - ifrom_x; weight_x[0] := 1 - weight_x[1]; total_red := 0.0; total_green := 0.0; total_blue := 0.0; total_alpha := 0.0; for ix := 0 to 1 do begin for iy := 0 to 1 do begin sli := apng.Scanline[ifrom_y + iy]; if isAlpha then ali := apng.AlphaScanline[ifrom_y + iy]; new_red := sli[ifrom_x + ix].rgbtRed; new_green := sli[ifrom_x + ix].rgbtGreen; new_blue := sli[ifrom_x + ix].rgbtBlue; if isAlpha then new_alpha := ali[ifrom_x + ix]; weight := weight_x[ix] * weight_y[iy]; total_red := total_red + new_red * weight; total_green := total_green + new_green * weight; total_blue := total_blue + new_blue * weight; if isAlpha then total_alpha := total_alpha + new_alpha * weight; end; end; slo := bTmp.ScanLine[to_y]; if isAlpha then alo := bTmp.AlphaScanLine[to_y]; slo[to_x].rgbtRed := Round(total_red); slo[to_x].rgbtGreen := Round(total_green); slo[to_x].rgbtBlue := Round(total_blue); if isAlpha then alo[to_x] := Round(total_alpha); end; end; apng.Assign(bTmp); bTmp.Free; end; Außerdem bin ich mir unsicher, ob das überhaupt der richtige Weg zum Weiterverfolgen ist. Ich bin doch sicherlich nicht der einzige, der seine Anwendungen für hochauflösende Bildschirme anpassen möchte. Wie habt Ihr das denn gemacht? Wie lässt sich meine Methode verbessern? |
AW: Wie skaliert man am besten die Grafiken einer TPngImageList?
Zitat:
|
AW: Wie skaliert man am besten die Grafiken einer TPngImageList?
Das ist mir klar. Wie gesagt ist es für den Moment nicht anders möglich. Es sind einfach zu viele Grafiken, um das kurzfristig alles neu zu machen. Die Skalierung ist nur ein leider notwendiger Zwischenschritt, damit die Anwendung bedienbar bleibt. Verwaschene Grafiken sind in dem Fall tatsächlich besser als kleine, in der Ecke klebende Farbkleckse.
Daher suche ich die beste Möglichkeit, diese Skalierung umzusetzen. |
AW: Wie skaliert man am besten die Grafiken einer TPngImageList?
Soll das plattformunabhängig werden, oder darf es auch nur für Windows sein? Nur für Windows gibt es eine kleine und feine Methode, die nahezu beliebige Grafikformate skaliert: Ich hatte hier mal im Forum etwas dazu geschrieben finds aber nimmer. Stattdessen ein SO Link:
![]() Sherlock |
AW: Wie skaliert man am besten die Grafiken einer TPngImageList?
Windows genügt. Danke für den Link. Werde das mal ausprobieren. Scheint ja immerhin ohne extra Komponenten wie GDI+ auszukommen.
Hattest Du dran noch etwas weitergebastelt oder in dem Beitrag (den Du nicht finden kannst) nur auf die gleiche Quelle verwiesen? |
AW: Wie skaliert man am besten die Grafiken einer TPngImageList?
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:16 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz