• GDlib und große Bilder

    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:
    $ini ini_get_all();
    echo 
    $ini['memory_limit']['global_value']; 
    Anhand von Beispielen möchte ich mal etwas näher auf Bilder, und das verarbeiten mit der GBlib eingehen.
    Als Vergleichsprogramm dient Adobe Photoshop.


    Dateigröße ist nicht Datenmenge

    Oft wird die Dateigröße eines Bildes in Bezug zur GDlib gebracht.

    ... mein Bild ist noch nur 56kb groß, es ist doch nicht so groß ...
    ... bekomme ich wie zu erwarten einen memory allocation error ...
    Nunja, die Dateigröße ist das Resultat nach dem Speichern des Bildes,
    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 !


    http://www.mediacix.de/images/pic_klein_366.html



    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
    
    Aha! Genau dies wird auch im Photoshop angezeigt

    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
    
    Bohhh, also fast doppelt soviel

    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)
  • Neue Blog-Einträge

    Adventure-PHP-Framework 1.12 erschienen

    Ich bin bisher nicht dazu gekommen - und wollte eigentlich die beiden links nennen: :arrow: http://www.golem.de/1008/77097.html :arrow:...

    20.08.2010 16:09

    Britische Regierung hält am IE6 fest

    Man könnte auch sagen "Tot erhoffte leben länger" :arrow: http://www.golem.de/1008/77035.html Leider sind halt in vielen Unternehmen speziell an den IE angepasste Programme im Einsatz, die es...

    20.08.2010 16:12

    Hosting-Dienst GitHub erreicht Millionen-Marke

    Während ich persönlich noch immer gerne SVN einsetze, ist git gerade voll im Trend. GitHub hatte die Tage zu vermelden, dass es mehr als eine Million Softwareprojekte "unter seinem Dach" hat....

    20.08.2010 16:15

    Screenshot unter Windows vom aktiven Fenster erstellen

    Der Trend, nicht nur einen Bildschirm bei der Arbeit am PC zu verwenden ist imho vorhanden. Wer - wie ich - gerne zwischendurch einen screenshot macht, der dürfte sich ggf. manches Mal geärgert...

    20.08.2010 16:20

    ListView-Spalten Automatisch ausrichten

    Listviews begegnen uns eigentlich jeden Tag aufs neue bei der täglichen Arbeit. Genauso oft nervt es, wenn man z.b. im Explorer Spalten verschieben muss, um einen Dateinamen einer Datei vollständig...

    24.08.2010 13:10
  • Neue Beiträge

    Sekundentakt

    Hi,

    ich weiß nicht genau, wie Deine Subselects aussehen. Aber falls die sich so ähnlich formulieren lassen:

    Code:
    SELECT something
    

    CONCAT_WS mit LEFT JOIN

    Sekundentakt 01.09.2010 15:30 Gehe zum letzten Beitrag
    DasMööp

    *ohje ... Antwort: Subselect *rolleye, damit fällt dann der JOIN weg.

    CONCAT_WS mit LEFT JOIN

    DasMööp 31.08.2010 13:29 Gehe zum letzten Beitrag
    DasMööp

    Hallo,

    bei einer Abfrage von zwei Tabellen ist in einer in zwei Spalten je die ID der einen hinterlegt und diese brauche ich in der CONCAT.

    CONCAT_WS mit LEFT JOIN

    DasMööp 31.08.2010 12:17 Gehe zum letzten Beitrag
    floppy

    Hallo DEVWinC, Hallo Spezialisten,

    ich stehe zur Zeit auf dem gleichen Problem, bei mir gibts beim BartPE (XP) nur einen BlueScreen nach

    [Booten] ISO-Images mit Bootloader starten & BartPE

    floppy 31.08.2010 10:48 Gehe zum letzten Beitrag

Impressum · Tutorials · Nutzungsbedingungen · thematisch sortierte Linklisten · Spendenaufruf · Team · Partnerprojekte

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48