![]() |
|
|
Themen-Optionen |
|
|
Nach oben #1 | |
|
Erfahrener Benutzer
Registriert seit: 18.03.2005
Beiträge: 576
|
Immer wieder kann man in einigen Foren-Beiträgen lesen das Thumbnail-Funktion nicht richtig funktioniert,
memory_limit ein Fatal error oder Bilder schwarz bleiben obwohl doch das Bild nicht so groß ist. Bei „groß” bezieht man sich immer wieder gern auf die Dateigröße des Bildes. Das dies ein Irrtum ist möchte ich an dieser Stelle darauf näher eingehen. GBlib und zu große Bilder: Bilder werden schwarz, fehlerhaft, abgeschnitten oder das Script bricht mit „Fatal error: Allowed memory size of 16777216 bytes” ab. Meist ist dies die Ursache weil der Speicherbedarf für die jeweilige Anwendung überschritten wurde. Im schlimmste Falle liegt auch ein Timeout vor :-) Das Hauptproblem liegt jedoch bei MEMORY_LIMIT, was man mit phpinfo() abrufen kann. Oder: PHP-Code:
Als Vergleichsprogramm dient Adobe Photoshop. Dateigröße ist nicht Datenmenge Oft wird die Dateigröße eines Bildes in Bezug zur GDlib gebracht. Zitat:
und hat somit keinen wirklichen Einfluss auf dem belegten Speicherplatz im Arbeitsspeicher. Die hier erwähnten 56kb ist nach der Komprimierung des Bildes entstanden. Der Sinn und Zweck einer Komprimierung ist es Farbtonschwankungen zusammenzufassen. z.B. Farbtonschwankung 244, 243, 243, 244, 244 (Pixelwerte), lässt sich verkürzen durch 5x244 Das beruht darauf, dass kleine Schwankungen in den Farbnuancen vom menschlichen Auge kaum wahrgenommen werden und deshalb ignoriert werden können. Unser Auge kann keine 16 Millionen Farben erkennen. Wird ein Bild mit ImageCreateFromJPEG(),ImageCreateFromPNG() oder ImageCreateTrueColor() geladen oder erzeugt, so werden die Farbinformationen pixelweise eingelesen und mit 40bit pro Pixel Farbtiefe neu erzeugt. Bei ImageCreateFromGIF() und ImageCreate() sind es weniger da hier nur mit 256 Farben gearbeitet wird. Somit ist hier auch der Speicherbedraf weniger. Da jedoch ImageCreate() z.B. für Fotos nicht in Frage kommt, möchte ich hierauf nicht näher eingehen. Wieso nun 40bit ? Die GDlib kann auch CMYK-Bilder und mit Alphakanal lesen. CMYK-Bilder arbeiten mit 32bit Farbtiefe, und der Alphakanal mit nochmal 8bit, was zusammen 40bit macht. Vermutlich ist die GDlib so als Standard eingestellt. Wird nun ein Bild mit der GDlib geladen, entsteht hier ein unkomprimiertes Bild im Arbeitsspeicher. Unkomprimiertes Bild deshalb, weil sich unkomprimierte Daten besser und schneller verarbeiten lassen. Wer mit Videoschnitt zu tun hat, wird sicher die gewaltigen Unterschiede kennen. Wieviele Farbinformationen eingelesen werden, bestimmt die Breite und Höhe des Bildes ! Beispiel mit Photoshop: Wir legen mal ein Beispielbild mit 2500 x 2000 px an. Hintergrundfarbe lassen wir mit Absicht mal weiß. Unten links wird uns schon die Datenmege im Arbeitsspeicher angezeigt. In diesem Beispiel sind das 14,3MB ! Wie kommt jetzt das Programm auf diese Angabe ? Ähnlich wie die GDlib arbeitet auch ein Grafikprogramm, alledings mit 24bit Farbtiefe bei RGB (Standard). Nehmen wir doch einmal ein Taschenrechner zur Hand, und rechnen es selber nach. Code:
Breite = 2500 px Höhe = 2000 px Farbtiefe = 24bit (3 * 8bit bei RGB) 2500px * 2000px * 24bit ------------------------ 8 * 1024 * 1024 (8388608) Datenmenge im Grafikprogramm 14,3 MB Und weil wir grad so schön beim rechnen sind, wiederholen wir diese Rechnung, allerdings diesmal für die GDlib mit 40bit. Code:
Breite = 2500 px Höhe = 2000 px Farbtiefe = 40bit (4 * 8bit bei CMYK + 8bit Alphakanal) 2500px * 2000px * 40bit ------------------------ 8 * 1024 * 1024 (8388608) Datenmenge = 23,8 MB Speichern wir unser Bild im Photoshop dochmal mit Qualität 70 ab, und schauen wie groß das Bild in der Dateigröße wird. Dann wird es ca. 144Kb groß werden, und würden wir das Bild als GIF mit 128 Farben speichern, so wäre das Bild dann nur noch 4Kb groß. Und warum ist das so ? Da unser Beispielbild nur aus einer weißen Fläche besteht, können alle Farbinformationen leicht zusammen gefasst werden. -> Siehe Komprimierung ... Dadurch ist das Bild nach dem Speichern wesentlich kleiner geowrden. Würden wir nun das Bild 4Kb GIF-Bild wieder im Photoshop laden, stellen auf Modus RGB um, hätten wir wieder unsere 14,3 MB im Speicher. Und die PHP-GDlib arbeitet nicht anders! Diese bisherige Beispiel soll mal etwas näher bringen, dass die Dateigröße nichts mit dem belegten Arbeitsspeicher zu tun hat. Dateigröße und Datenmenge sind 2 völlig unterschiedliche Dinge. Arbeiten mit der GDlib: Oft wird die GDlib dazu benutzt, um Bilder zu verkleinern, zu verändern etc. und wieder neu abspeichern. Bei den meisten diesen Varianten werden 2 oder teilweise mehrere Bild mit der GDlib erzeugt, um das gewünschte Resultat zu erhalten. Unser bisheriges Beispiel bezog sich nur auf ein Bild ! Bei einen Thumbnail-Script werden mind. 2 Bilder erzeugt, dann addiert sich natürlich der beglegte Speicherbedarf pro Bild. Zudem kommt noch hinzu, dass meistens Bilder von der Digicam benutzt werden, derren Breite und Höhe noch größer sind als unser Beispiel. ImageCreate oder ImageCreateTrueColor Der Speicherbedarf bei ImageCreate und ImageCreateTrueColor ist unterschiedlich. Dazu möchte ich auf diesen Beitrag verweisen: http://www.mediacix.de/blog/ImageCre...-161-2007.html Ich glaube nach diesen Beispielen und Rechnungen sollte auch die Wichtigkeit von ImageDestroy() erkennbar sein. Oft sehe ich Scripte wo ImageDestroy() ausser acht gelassen wird. Benutzte man eine Thumbnail-Funktion ohne ImageDestroy() innerhalb einer Schleife, hat sich die Sache ganz schnell erledigt, weil es zum Speicherüberlauf kommt. Gleiches gilt auch, wenn von einen Bild eine oder meherer Kopien gemacht wird. http://www.mediacix.de/code/Thumbnai...h-98-code.html Also ein Originalbild mit ImageCreateFromJPEG() laden, eine neues Bild mit ImageCreateTreuColor() erzeugen, und vielleicht noch ein Wasserzeichenbild auch mit ImageCreateFromJPEG() einbinden. Dann werden hier schon 3 Image-Ressourcen erzeugt, die kräftig am Speicher fressen. Die Aufgabe von ImageDestroy() ist es nunmal, den belegten Speicherbedarf wieder frei zu geben, welcher durch das zuvor erzeugte Bild entstanden ist. Dabei muss ImageDestroy für jede erezugte Image-Ressourcen benutzt werden! Ein Beispiel dafür: http://www.mediacix.de/code/GDlib-un...f-85-code.html Ich hoffe, ich konnte das Verhalten der GDlib und den Einfluss der Dateigröße dazu etwas näher bringen. MfG CIX88 [Änderungen vom Beitrag sind nicht ausgeschlossen] (Originalbeitrag: http://www.mediacix.de/blog/PHP-GDli...-169-2008.html) Geändert von CIX88 (04.01.2008 um 18:06 Uhr). Grund: Update vom Beitrag |
|
|
|
|
![]() |
| Lesezeichen |
| Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1) | |
| Themen-Optionen | |
|
|
Ähnliche Themen
|
||||
| Thema | Autor | Forum | Antworten | Letzter Beitrag |
| Freie Bilder | Jan | Plauderecke | 2 | 09.05.2007 14:37 |
| FCKEditor: Vorgaben für Bilder | Basti | JavaScript und AJAX | 5 | 29.04.2007 16:46 |
| Viele Bilder in einem Ordner => Ladezeitproblem | heohni | PHP-Programmierung | 7 | 06.10.2006 23:25 |
| PHP Bilder verkleinern | robo47 | PHP-Programmierung | 30 | 25.09.2006 19:50 |
| gdLib - Bilder rotieren | Chr!s | PHP-Programmierung | 19 | 05.02.2006 20:03 |