AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Delphi Wie skaliert man am besten die Grafiken einer TPngImageList?
Thema durchsuchen
Ansicht
Themen-Optionen

Wie skaliert man am besten die Grafiken einer TPngImageList?

Ein Thema von CodeX · begonnen am 26. Apr 2016 · letzter Beitrag vom 27. Apr 2016
Antwort Antwort
CodeX

Registriert seit: 30. Okt 2004
471 Beiträge
 
Delphi 12 Athens
 
#1

Wie skaliert man am besten die Grafiken einer TPngImageList?

  Alt 26. Apr 2016, 14:27
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.



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;
SmoothResize ist dabei eine Funktion von hier:
http://cc.embarcadero.com/Item/25631
Delphi-Quellcode:
 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;
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.
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?
Miniaturansicht angehängter Grafiken
menuscale.png  
Nur Delphi schafft es, einem ein Lächeln zu schenken, wenn man sich beim Schreiben von := vertippt und stattdessen ein :) erscheint.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.009 Beiträge
 
Delphi 12 Athens
 
#2

AW: Wie skaliert man am besten die Grafiken einer TPngImageList?

  Alt 26. Apr 2016, 15:13
Außerdem bin ich mir unsicher, ob das überhaupt der richtige Weg zum Weiterverfolgen ist.
Wenn du nicht mit verwaschenen, unscharfen und eventuell fehlerhaften Grafiken leben willst, kommst du um ein Neuzeichnen in den jeweils benötigten Auflösungen nicht herum. Wenn man es richtig angefangen hat, liegen die Grafiken in einem Vektorformat vor und werden dann in den jeweiligen Auflösungen erstellt und bei Bedarf nachbearbeitet. Wenn nur 16x16 Pixel verfügbar sind, ist das allerdings die denkbar schlechteste Ausgangsbasis.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
CodeX

Registriert seit: 30. Okt 2004
471 Beiträge
 
Delphi 12 Athens
 
#3

AW: Wie skaliert man am besten die Grafiken einer TPngImageList?

  Alt 26. Apr 2016, 15:23
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.
Nur Delphi schafft es, einem ein Lächeln zu schenken, wenn man sich beim Schreiben von := vertippt und stattdessen ein :) erscheint.
  Mit Zitat antworten Zitat
Benutzerbild von Sherlock
Sherlock

Registriert seit: 10. Jan 2006
Ort: Offenbach
3.763 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Wie skaliert man am besten die Grafiken einer TPngImageList?

  Alt 26. Apr 2016, 15:46
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: http://stackoverflow.com/questions/1...-kind-of-image

Sherlock
Oliver
Geändert von Sherlock (Morgen um 16:78 Uhr) Grund: Weil ich es kann
  Mit Zitat antworten Zitat
CodeX

Registriert seit: 30. Okt 2004
471 Beiträge
 
Delphi 12 Athens
 
#5

AW: Wie skaliert man am besten die Grafiken einer TPngImageList?

  Alt 26. Apr 2016, 16:05
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?
Nur Delphi schafft es, einem ein Lächeln zu schenken, wenn man sich beim Schreiben von := vertippt und stattdessen ein :) erscheint.
  Mit Zitat antworten Zitat
Benutzerbild von Sherlock
Sherlock

Registriert seit: 10. Jan 2006
Ort: Offenbach
3.763 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Wie skaliert man am besten die Grafiken einer TPngImageList?

  Alt 27. Apr 2016, 07:00
In diesem Thread kommts http://www.delphipraxis.net/183061-k...che-dinge.html

Sherlock
Oliver
Geändert von Sherlock (Morgen um 16:78 Uhr) Grund: Weil ich es kann
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:50 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz