AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

PNGImageList zu langsam / Alternative gesucht

Ein Thema von Spes · begonnen am 23. Jan 2008 · letzter Beitrag vom 24. Jan 2008
Antwort Antwort
Spes

Registriert seit: 21. Aug 2007
14 Beiträge
 
#1

PNGImageList zu langsam / Alternative gesucht

  Alt 23. Jan 2008, 22:14
Hi zusammen,

ich würde gerne die PngImageList verwenden transparente Icons an verschiedenen Stellen (Images, Menüs, Tabellen, ...) anzeigen zu lassen. Hierzu verwende ich knapp 100 Icons jeweils in 2 Größen (16x16 und 32x32), welche ich wie folgt (abgeschaut bei stz) lade:
Code:
PngList := TPngImageList.Create(nil);
PngItem := PngList.PngImages.Add ;
PngItem.PngImage.LoadFromFile(Filename);
Und dann beispielsweise wie folgt auf ein Image bringe
Code:
ImageFront.Picture.Assign(PngList.PngImages[I].PngImage);
Bei Laden konnte ich beobachten, wie folgende Methoden abgearbeitet werden:
PngList.PngImages.Add (PngImages ist vom Typ TPngImageCollectionItems)
-> TPngImageCollectionItem.Create
-> TCollectionItem.Create
-> TCollection.RemoveItem
-> TList.Remove
-> TList.IndexOf
Beim IndexOf rennt der dann natürlich im Worst-Case über die gesammte Liste und zwar für jedes Icon, so dass ich eine Laufzeit von irgendwas in 0(n²) je PngImageList bekomme. Da ich jetzt leider auch noch zwei Listen habe - jeweils eine pro Icongröße - dauert der Vorgang bei mir eine knappe Minute, bis das Programm gestartet ist.

Kann ich das irgendwie Beschleunigen ohne die Icon-Anzahl eingrenzen zu müssen?

Folgende Ideen kamen mir dabei:
- Irgendwie ein Array von TPngObjects auf die TPngList casten?
- Nur eine Liste anlegen und daraus dann die andere per Skalieren der PNGs erzeugen?
- Auf entweder die TCollection oder die TList verzichten (brauche ich wirklich beides?)?

Weiterhin habe ich versucht, die TPngImageCollectionItems zu entfernen und durch eine von TObjectList abgeleitete Liste zu ersetzen. Das Laden ging dann zwar fühlbar schneller, aber die 16x16-Icons wurden dann nicht mehr angezeigt (die 32er wohl - komisch).

Gibt es sonst vielleicht irgendwo ein Tutorial oder eine Anwendung in der ich mir die richtige Verwendung der PngImageList mal ansehen kann? (Google spuckt zur "PngImageList" bzw. "TPngImageList" jeweils lediglich drei Seiten aus und beim [ulr=http://www.delphipraxis.net/internal_redirect.php?t=111689&highlight=pngimagel ist]Secretizer[/url] finde ich die Verwendung der PngImageLists ilTreeIcons und ilGlyphs nicht).
  Mit Zitat antworten Zitat
Benutzerbild von Dani
Dani

Registriert seit: 19. Jan 2003
732 Beiträge
 
Turbo Delphi für Win32
 
#2

Re: PNGImageList zu langsam / Alternative gesucht

  Alt 24. Jan 2008, 00:05
Verwende ImgList.PngImages.BeginUpdate und ImgList.PngImages.EndUpdate, das dürfte den Vorgang erheblich beschleunigen.

Edit: Beispiel ohne Fehlerbehandlung

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
const
  TimeFormat = 'nn:ss:zzz';
var I: Integer;
    StartTime, EndTime: TDateTime;
    TempFileName: String;
    TempImg: TPNGObject;
    TempBMP: TBitmap;
    RandomRect: TRect;
    C: TCanvas;
begin
  TempBMP := TBitmap.Create;
  TempBMP.Width := 32;
  TempBMP.Height := 32;

  C := TempBMP.Canvas;
  C.Pen.Style := psSolid;
  C.Brush.Style := bsSolid;
  for I := 0 to 100 do begin
    C.Pen.Color := Random(clWhite);
    C.Brush.Color := Random(clWhite);
    RandomRect := Rect(Random(TempBMP.Width), Random(TempBMP.Height),
                  Random(TempBMP.Width), Random(TempBMP.Height));
    C.FillRect(RandomRect);
  end;

  TempFileName := IncludeTrailingPathDelimiter(GetEnvironmentVariable('Temp')) +
                  'PngImageListTest.png';

  TempImg := TPNGObject.Create;
  TempImg.Assign(TempBMP);
  TempImg.SaveToFile(TempFileName);
  TempBMP.Free;
  TempImg.Free;

  StartTime := Now;
  ImgList.PngImages.BeginUpdate;
  for I := 0 to 300 do begin
    ImgList.PngImages.Add(False).PngImage.LoadFromFile(TempFileName);
  end;
  ImgList.PngImages.EndUpdate;
  EndTime := Now;
  Label1.Caption := 'Total: ' + FormatDateTime(TimeFormat, EndTime - StartTime);
end;
Dani H.
At Least I Can Say I Tried
  Mit Zitat antworten Zitat
Spes

Registriert seit: 21. Aug 2007
14 Beiträge
 
#3

Re: PNGImageList zu langsam / Alternative gesucht

  Alt 24. Jan 2008, 21:18
Vielen Dank Dani
Dank deinem Beispiel klappts jetzt in unter einer Sekunde. Wie bist du darauf gekommen die BeginUpdate und EndUpdate zu verwenden? ist das unter Delphi gängige Praxis, oder gabs dazu irgendwo Hinweise?

Vg,
Spes
  Mit Zitat antworten Zitat
Benutzerbild von Dani
Dani

Registriert seit: 19. Jan 2003
732 Beiträge
 
Turbo Delphi für Win32
 
#4

Re: PNGImageList zu langsam / Alternative gesucht

  Alt 24. Jan 2008, 21:27
Bin den Code per Debugger durchgegangen und dort wurde nach jeder Einfügeoperation die Update-Methode der TPngImageCollectionItems aufgerufen:
Delphi-Quellcode:
procedure TPngImageCollectionItems.Update(Item: TCollectionItem);
begin
inherited Update(Item);
if FOwner is TPngImageList
then TPngImageList(FOwner).CopyPngs;
end;
wobei CopyPngs so aussieht:

Delphi-Quellcode:
procedure TPngImageList.CopyPngs;
var
   I: Integer;
   Png: TPNGObject;
   Icon: HIcon;
begin
//Are we adding a bunch of images?
if FLocked > 0
then Exit; {... danach werden alle PNGs neu erstellt}
...dann erst hab ich die Methoden BeginUpdate und EndUpdate entdeckt, hatte vorher keine Ahnung.

Zitat:
Ist das unter Delphi gängige Praxis
Ja, wenn mehrere Datensätze sich ändern, ohne dass die View (also Formulare usw) darauf reagieren soll, sollte man diese Methoden verwenden. Man findet sie z.B. auch in TListItem oder TStrings.
Dani H.
At Least I Can Say I Tried
  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 18: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