AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi PNG in mehrere Teile aufteilen
Thema durchsuchen
Ansicht
Themen-Optionen

PNG in mehrere Teile aufteilen

Ein Thema von Gausi · begonnen am 2. Feb 2025 · letzter Beitrag vom 3. Feb 2025
 
Benutzerbild von Gausi
Gausi

Registriert seit: 17. Jul 2005
900 Beiträge
 
Delphi 11 Alexandria
 
#1

PNG in mehrere Teile aufteilen

  Alt 2. Feb 2025, 11:12
Zuerst dachte ich, das ginge ganz einfach. Dann habe ich ChatGPT gefragt, und das hat rumhalluziniert und dabei den Knackpunkt gewissenhaft ignoriert. Und weil ich weiß, dass hier ein paar PNG-Experten unterwegs sind, frage ich lieber hier mal nach.

Mit Blick auf Unterstützung für Skalierung möchte ich zur Laufzeit ein paar ImageCollections füllen, die dann wie üblich VirtualImageListen als Quelle dienen. Der Plan ist (um die Anzahl der Dateien klein zu halten), dass alle Icons für eine VirtualImageList in einer Datei liegen (bzw. je eine Datei für 100%, 125%, 150%, ...). Zur Laufzeit soll diese große PNG-Datei dann häppchenweise in die ImageCollection eingefügt werden - inklusive Transparenz und Alphakanal. Und da erscheint mir der Code, den ich mir zusammengesucht habe, etwas umständlich.

Direkt eincompilieren (gefüllte ImageCollection auf einem DataModul etc) möchte ich die Bilddaten nicht, da ich mehrere Icon-Sets zur Auswahl mitliefern möchte, die erst zur Laufzeit geladen werden sollen - und die ggf. auch vom Anwender ergänzt werden können.

Quelle u.a. von Stackoverflow

Delphi-Quellcode:
procedure LoadImagesFromPNG(const AFileName: string; AImageCollection: TImageCollection;
  AImageSize: Integer);
var
  SourcePng, singleIconPNG: TPngImage;
  i, Count: Integer;
  Item: TImageCollectionItem;
  newImageCollectionItem : TImageCollectionSourceItem;
  SrcRect: TRect;
  srcAlphaArray: pByteArray;
  destAlphaArray: pByteArray;
  X, Y, xOffset, yOffset: Integer;
begin
  SourcePng := TPngImage.Create;
  try
    SourcePng.LoadFromFile(AFileName);
    Count := SourcePng.Width div AImageSize;
    for i := 0 to Count - 1 do begin
      yOffset := 0;
      xOffset := i * aImageSize;
      SrcRect := Rect(i * AImageSize, 0, (i + 1) * AImageSize, AImageSize);

      singleIconPNG := TPNGImage.CreateBlank(COLOR_RGBALPHA, 8, AImageSize, AImageSize);
      try
        singleIconPNG.CreateAlpha;
        singleIconPNG.Canvas.CopyMode := cmSrcCopy;
        singleIconPNG.Canvas.CopyRect(Rect(0, 0, AImageSize, AImageSize), SourcePng.Canvas, SrcRect);
        if SourcePng.TransparencyMode = ptmPartial then begin
          // Update destination png with tranparency data from original
          for Y := 0 to SourcePng.Height - 1 do begin
            srcAlphaArray := SourcePng.AlphaScanline[Y];
            destAlphaArray := singleIconPNG.AlphaScanline[Y + YOffset];
            for X := 0 to SourcePng.Width - 1 do
              destAlphaArray^[X] := srcAlphaArray^[X + XOffset];
          end;
        end;

        // Testweise als einzelnes PNG speichern
        singleIconPNG.SaveToFile(AFilename + i.ToString + '.png');

        // Neues Item in der ImageCollection hinzufügen
        // Code von ChatGPT, dass muss natürlich noch angepasst werden für mehrere Auflösungen
        Item := AImageCollection.Images.Add;
        Item.Name := Format('%s_%d', [ExtractFileName(AFileName), i]);
        newImageCollectionItem := Item.SourceImages.Add;
        newImageCollectionItem.Image.Assign(singleIconPNG);
      finally
        singleIconPNG.Free;
      end;
    end;
  finally
    SourcePng.Free;
  end;
end;
Die PNGComponents von Uwe Raabe habe ich kurz danach auch gefunden, die Funktion SlicePNG ist ja recht ähnlich dazu. Die würde ich grade auch bevorzugen - zuerst Slicen und für jede Auflösungsstufe die PNG-Listen erstellen lassen und die dann in die ImageCollection schaufeln. Frage am Rande: Kann ich die mit Quellenangabe in mein OpenSource-Projekt übernehmen? Finde da keine Lizenzangabe...

Mein "Problem" ist nun, ob sich der Aufwand dann überhaupt noch "lohnt". Meine Hoffnung ist, dass das Laden einer Datei und Aufteilen in kleinere Grafiken schneller geht als das Laden von vielen einzelnen Dateien. Bei dem Code bin ich mir da aber nicht mehr so sicher. Es geht dabei um ca. 100 Icons (aufgeteilt in 3 Gruppen), die ich in 4 oder 5 Auflösungen anbieten möchte (Für 100-200% Skalierung). Also ~500 Dateien einzeln laden vs. ~5 (bzw. 15) Dateien laden und splitten.

Hat jemand in der Hinsicht Erfahrungswerte oder kann eine kompetente Schätzung abgeben, was sinnvoller wäre?
Being smart will count for nothing if you don't make the world better. You have to use your smarts to count for something, to serve life, not death.
  Mit Zitat antworten Zitat
 


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 13:32 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 by Thomas Breitkreuz