2009-05-07 9 views
5

Ich muss Thumbnails von Bildern in einem bestimmten Verzeichnis anzeigen. Ich benutze TFileStream, um die Bilddatei vor dem Laden des Bildes in eine Bildkomponente zu lesen. Die Bitmap wird dann auf die Thumbnail-Größe skaliert und einer TImage-Komponente auf einer TScrollBox zugewiesen.Was ist der schnellste Weg zum Laden und Ändern der Größe eines Bildes?

Es scheint zu funktionieren, aber verlangsamt ziemlich viel mit größeren Bildern.

Gibt es eine schnellere Möglichkeit, (Image-) Dateien von der Festplatte zu laden und deren Größe zu ändern?

Danke, Pieter

Antwort

5

Nicht wirklich. Sie können die Größe in einem Hintergrundthread ändern und ein "Platzhalter" -Bild verwenden, bis die Größenänderung abgeschlossen ist. Ich würde dann diese Größe Bilder in eine Art von Cache-Datei für die spätere Verarbeitung speichern (Windows tut dies und ruft den Cache thumbs.db im aktuellen Verzeichnis).

Sie haben mehrere Optionen für die Thread-Architektur. Ein einzelner Thread, der alle Bilder verarbeitet, oder ein Thread-Pool, in dem ein Thread nur ein einzelnes Bild verarbeiten kann. Die Bibliothek ist noch eine andere Art und kann die Dinge ziemlich einfach halten.

+0

Meine App verwendet jetzt Platzhalter und Threads (skamradt, mghie) und es funktioniert perfekt.Die Vorschaubilder werden wie von Stijn Sanders vorgeschlagen extrahiert. Vielen Dank. Pieter. –

+0

Leider ist AsyncCalls tot (eingestellt). – Ampere

5

Ich werde die Antwort von skamradt mit dem Versuch, dies so schnell wie möglich zu gestalten, ergänzen. Dazu sollten Sie

  • optimize I/O
  • Verwendung mehrere Threads Verwendung mehrere CPU-Kern, und zu halten, auch ein einzelner CPU-Kern arbeiten, während Sie lesen (oder schreiben) -Dateien
zu machen

Die Verwendung von mehreren Threads impliziert, dass die Verwendung von VCL-Klassen für die Größenänderung nicht funktioniert, da die VCL nicht threadsicher ist und alle Hacks, die sich darum herum befinden, nicht gut skalieren. efg's Computer Lab enthält Links für Bildverarbeitungscode.

Es ist wichtig, mehrere gleichzeitige E/A-Vorgänge nicht zu verursachen, wenn mehrere Threads verwendet werden. Wenn Sie die Thumbnails in Dateien zurückschreiben, sollten Sie sie nach dem Lesen einer Datei vollständig lesen. Sobald Sie mit dem Schreiben einer Datei begonnen haben, sollten Sie sie auch vollständig schreiben. Wenn Sie beide Operationen miteinander verschachteln, wird Ihre E/A-Operation beendet, da Sie möglicherweise viele Suchvorgänge am Festplattenkopf durchführen müssen.

Für beste Ergebnisse sollte das Lesen (und Schreiben) von Dateien auch nicht im Hauptthread (GUI) Ihrer Anwendung erfolgen. Das würde folgendes Design vorschlagen:

  • Lassen Sie einen Thread Dateien in TGraphic-Objekte lesen und diese in eine threadsichere Liste einfügen.
  • Lassen Sie einen Thread-Pool auf der Liste der Dateien in Originalgröße warten und lassen Sie einen Thread ein TGraphic-Objekt verarbeiten, ändern Sie die Größe in ein anderes TGraphic-Objekt und fügen Sie dieses einer anderen threadsicheren Liste hinzu.
  • Benachrichtigen Sie den GUI-Thread für jedes Miniaturbild, das der Liste hinzugefügt wurde, damit es angezeigt werden kann.
  • Wenn Vorschaubilder in Datei geschrieben werden sollen, tun Sie dies auch im Lese-Thread (siehe oben für eine Erklärung).

Edit:

Auf Re-Lektüre Ihre Frage, die ich feststellen, dass Sie vielleicht nur ein Bild, um die Größe benötigen, wobei in diesem Fall ein einzelner Hintergrund-Thread natürlich genug ist. Ich werde meine Antwort trotzdem an Ort und Stelle lassen, vielleicht wird es irgendwann für jemand anderen von Nutzen sein. Es ist das, was ich von einem meiner letzten Projekte gelernt habe, wo das endgültige Programm ein wenig mehr Geschwindigkeit benötigt hätte, aber nur zu Spitzenzeiten nur etwa 75% der Quad-Core-Maschine verwendet hat. Die Entkopplung von E/A von der Verarbeitung hätte den Unterschied gemacht.

5

Ich verwende oft TJPEGImage mit Scale: = jsEighth (in Delphi 7). Dies ist sehr schnell, da die JPEG-Dekomprimierung viele Daten überspringen kann, um eine Bitmap von nur einem Achtel der Breite und Höhe zu füllen.

Eine weitere Option ist die shell's method to extract a thumbnail zu verwenden, die auch ziemlich schnell ist

+0

das sieht gut aus. Ich war verzweifelt, das im letzten Jahr herauszufinden, aber jetzt interessiert mich nicht mehr zu viel. Aber ich kann immer noch einige meiner Apps mit dem TJPEGImage.Scale-Ansatz reparieren. Danke –

1

ich in der Vision Geschäft bin, und ich einfach die Bilder auf die GPU laden OpenGL. (typischerweise 20x 2048x2000x8bpp pro Sekunde), ein bmp pro Textur, und lassen Sie die Grafikkarte skalieren (win32, Mike Lischkes opengl-Header)

Upload von einem solchen Bild kostet 5-10ms je nach genauen Grafikkarte (wenn nicht integriert und nvidia 7300 Serien oder neuer. Ganz neuere integrierte GPUs könnten auch machbar sein). Skalierung und Anzeige von Kosten 300us. Das bedeutet, dass Kunden wie verrückt schwenken und zoomen können, ohne die App zu berühren. Ich zeichne ein Overlay (das früher ein tmetafile war, aber jetzt ein eigenes Format ist) darüber.

Mein größtes Bild ist 4096x7000x8bpp das zeigt und in weniger als 30ms skaliert. (GF 8600)

Eine Einschränkung dieser Technologie ist die maximale Texturgröße. Es kann aufgelöst werden, indem das Bild in mehrere Texturen zerlegt wird, aber ich habe mich noch nicht gestört, weil ich die Systeme mit der Software liefere.

(einige typische Größen: nv6x00 Serie: 2k * 2k aber das Hochladen Pause nur etwa ist selbst im Vergleich zu GDI nv7x00 Serie. 4k * 4k Für mich ist die Baseline-Karten GF7300 die sind wie $ 20-40 nv8x00 Serie: 8k * 8k )

Beachten Sie, dass dies nicht für alle sein kann. Aber wenn Sie in der glücklichen Situation sind, Hardwaregrenzen zu spezifizieren, könnte es funktionieren. Das Hauptproblem sind Laptops wie Thinkpads, deren GPUs älter sind als die avg-Laptops, die wiederum oft eine Generation hinter Desktops stehen.

Ich habe OpenGL über DirectX gewählt, weil es in der Zeit statischer und einfacher ist, nicht spielbezogene Beispiele zu finden.

+0

sehr informativ aber off-topic. –

+0

ich fand das was ich suchte. Danke! –

0

Nutzen Sie die Windows-Kapazität, um Thumbnails zu erstellen. Denken Sie daran, dass versteckte Thumbs.db-Dateien in Ordnern, die Bilder enthalten?

Ich habe etwas wie diese Funktion aber in VB implementiert. Meine Software ist in der Lage, Miniaturen von 100 Dateien (gemischte Größe) in etwa 10 Sekunden zu erstellen.

Ich kann es jedoch nicht nach Delphi konvertieren.

0

Versuchen Sie, die Graphics32 library zu betrachten: es ist sehr gut im Zeichnen von Dingen und funktioniert groß mit Bitmaps. Sie sind Thread - Safe mit gutem Beispiel, und es ist völlig kostenlos.

Verwandte Themen