ImageFromJPEG wirft Fehler

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • ImageFromJPEG wirft Fehler

    Hallo miteinander,

    ich hab schon viel gegoogelt und hatte viel Kontakt mit dem Support von 1und1, aber ich komm nicht weiter, evtl. könnt ihr helfen. Folgende Situation:

    - php-Script, dass Bilder am Server auf eine bestimmte Größe rechnet und überschreibt
    - liest automatisch alle JPGs eines Ordners und verarbeitet sie
    - klappt mit allen Testbildern wunderbar, Dateien bis 20 MB kein Problem.
    - jetzt lade ich JPGs von einer Digicam hoch (ca. 1,9 MB pro Bild) und das Script wirft sofort folgenden Fehler:
    Fatal error: Out of memory (allocated 33030144) (tried to allocate 3264 bytes) in /homepages/27/d25171253/htdocs/_php/functions.php on line 160
    PHP-Code:
    $old_jpg=imagecreatefromJPEG($bild_am_server); 
    - Paralleltest an einem IIS5 mit gleichem Bildmaterial ergab kein Problem

    Mir ist klar, dass irgendwas diese Unmenge an Speicher allokiert, ABER WAS?

    Ich hab keinen Zugriff auf php.ini, aber der Support sagt folgendes:
    Bitte beachten Sie auch folgende Einschränkungen:
    - RAM: 32MB
    - NPROC: 24 (d.h.: In Ihrem Vertrag dürfen bis zu 24 Prozesse gestartet
    - max. Laufzeit 10 Sek.
    PHP-Version: 5.2.11
    GD Version bundled (2.0.34 compatible)

    Ich bin für jeden Tip offen.
    Danke
    Gruß
    Michel

  • #2
    Hallo,

    32MB sind für Bildverarbeitung wirklich etwas wenig. Dennoch kannst auch du etwas tun. Benutzt du zwischendurch imagedestroy, wenn du mehrere Bilder in einem Skript verarbeitest? Willst du mal deinen Code posten? Vielleicht findet sich ja noch die eine oder andere Schwachstelle, die man auch weniger speicherhungrig coden könnte.

    Gruß,

    Amica
    [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
    Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
    Super, danke!
    [/COLOR]

    Kommentar


    • #3
      Wenn es sich bei den 1,9 MB grossen Bildern um JPGs handelt, kann es gut sein, daß schon ein einziges Bild den Speicher vollmacht. Es muß schließlich ausgepackt werden und liegt dann in Originalgröße (Breite x Höhe x min. 3 oder 4 bytes) im Speicher.

      Kommentar


      • #4
        Zitat von Lengen1971 Beitrag anzeigen
        Hallo miteinander,
        - jetzt lade ich JPGs von einer Digicam hoch (ca. 1,9 MB pro Bild) und das Script wirft sofort folgenden Fehler:
        Wie gross (ausmaße) ist denn das Bild, was Du da einlesen willst?

        Ansonsten check einfach mal den Speicherverbrauch...

        PHP-Code:
        <?php
        /*****
        *  - Example CIX88 -
        *  Legende zu den benutzen Konstanten:

        *  TP = relativer Pfad zu einer Bilddatei
        *  CL_PHP = absoluter Pfad zu einer PHP-Klasse oder extra Modul
        *  CL_TTF = absoluter Pfad zu einer TTF-Datei
        *  CL_FPDF = absoluter Pfad zu einer FPDF-Klasse oder extra Modul
        *  CL_IMG = absoluter Pfad zu einer Bilddatei
        *  CL_AUDIO = absoluter Pfad zu einer Audiodatei

        *  Die hier benutzten Konstanten beziehen sich nur auf diese Beispiele.
        *  ! Der Pfad muss natürlich auf deine Gegebenheiten angepasst werden !
        */

        error_reporting(E_ALL);

        /*
        Zum Test wird ein Bild mit 2000x2000 Pixel erstellt.
        */

            
        function GetMem$text ) {
                
        $text '<p>'.$text.' : '.sprintf("%.3lf"memory_get_usage()/1024/1024 ). ' MB im Speicher </p>';
                return 
        $text;
            }

            echo 
        GetMem('Scriptanfang');

            
        $image ImageCreateTrueColor20002000);
                echo 
        GetMem('vor ImageDestroy() bei ImageCreateTrueColor');

            
        ImageDestroy($image);
                echo 
        GetMem('nach ImageDestroy() bei ImageCreateTrueColor');


            
        $image ImageCreate20002000);
                echo 
        GetMem('vor ImageDestroy() bei ImageCreate');

            
        ImageDestroy($image);
                echo 
        GetMem('nach ImageDestroy() bei ImageCreate');


            
        $ini ini_get_all();
            echo 
        'verfügbar: '$ini['memory_limit']['global_value'];
        ?>
        also hier ein Bild mit 2000x2000 Pixel...

        vor ImageDestroy() bei ImageCreateTrueColor : 19.189 MB im Speicher

        Also 19mb für das Bild. Soll davon nun noch ein Thumbnail oder sonstwelche Kopieen im Speicher gehalten werden, dann sind das schnell mal 2-3 mal so viel -> 60mb...

        Kannst ja mal mit dem Script hier deinen Speicherverbauch tesen...

        PS: Vielen Dank an cix für das hier verwendete Codeschnippet...

        Kommentar


        • #5
          Hallo miteinander

          und danke für die vielen Tips, ich konnte das Problem noch nicht lösen.

          @AmicaNoctis
          ja, ich benutze imagedestroy. Es ist aber ja nur ein Bild für die Bearbeitung vorgesehen, hier der Code:
          PHP-Code:
          function ML_getResizedImage($bild_am_server,$lange_seite)
          {
            if (
          $lange_seite==|| $lange_seite=="" || $lange_seite==false$lange_seite=600;
                  
            
          $size=getimagesize($bild_am_server);
              
            if (
          $size[0]>$lange_seite || $size[1]>$lange_seite)
           {
              
          // Image größer als lange_seite
            
          $size[0]>$size[1]?$faktor=$size[0]/$lange_seite:$faktor=$size[1]/$lange_seite;
            if (
          $size[0]>$size[1]) 
            {
              
          $n_width=$lange_seite;
              
          $n_height=$size[1]/$faktor;
            }
            else
            {
              
          $n_height=$lange_seite;
              
          $n_width=$size[0]/$faktor;
            }
            
          $jpg imagecreatetruecolor($n_width,$n_height);
            
          $old_jpg=imagecreatefromJPEG($bild_am_server);                

            
          imagecopyresampled($jpg,$old_jpg,0,0,0,0,$n_width,$n_height,$size[0],$size[1]);
            
          imagedestroy($old_jpg);
                      
            
          //unlink($bild_am_server);
            
          imagejpeg  ($jpg,$bild_am_server,90);
                      
            if (
          file_exists($bild_am_server)) return true;    
            else return 
          false;    
            }
            else
            {
              
          // Image nicht größer als lange_seite
              
          return true;
            }        

          @pekka:
          getimagesize gibt folgendes aus:
          PHP-Code:
          Array ( [0] => 3264 [1] => 2448 [2] => [3] => width="3264" height="2448" [bits] => [channels] => [mime] => image/jpeg 
          Hm... 8 channels, das ergibt 63922176 Bytes also. ca. 60 MB, das kann ja nicht gehen...

          @DonManfred:
          Ausgabe deines Scriptes:
          PHP-Code:
          Scriptanfang 0.130 MB im Speicher

          vor ImageDestroy
          () bei ImageCreateTrueColor 19.257 MB im Speicher

          nach ImageDestroy
          () bei ImageCreateTrueColor 0.131 MB im Speicher

          vor ImageDestroy
          () bei ImageCreate 7.813 MB im Speicher

          nach ImageDestroy
          () bei ImageCreate 0.130 MB im Speicher
          verf
          &#65533;gbar: 40M 

          Danke für alle Hinweise und Tips.

          Gruß
          Michael

          Kommentar


          • #6
            Vielleicht erlaubt dein Provider ImageMagick-Aufrufe? IM läuft m.W. immer außerhalb der Skripteigenen RAM-Beschränkungen.

            Kommentar


            • #7
              Hm... 8 channels, das ergibt 63922176 Bytes also. ca. 60 MB, das kann ja nicht gehen...
              Nein, es ergibt 23970816 Byte, also ca. 23,5MB. Bits steht für die Farbtiefe pro Kanal. Es sind drei Kanäle (Rot, Grün und Blau), die jeweils mit 255 verschiedenen Helligkeitsstufen belegt werden können, was sich mit 8Bit = 1Byte bewerkstelligen lässt. Es sind wie gesagt 3 Kanäle, also braucht ein Pixel des Bildes 3Byte im Speicher.

              Wenn ich deinen Code vom kurzen Überfliegen richtig interpretier, dann erzeugst du 2 Bilder im Speicher, mit jeweils über 20MB und schießt somit über dein Limit von 40MB hinaus.
              Zuletzt geändert von Quetschi; 27.10.2009, 13:05.
              Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
              Schön - etwas Geschichte kann ja nicht schaden.
              Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

              Kommentar


              • #8
                Zitat von pekka Beitrag anzeigen
                Vielleicht erlaubt dein Provider ImageMagick-Aufrufe? IM läuft m.W. immer außerhalb der Skripteigenen RAM-Beschränkungen.
                Da bin ich mir grad nicht sicher - evtl. könnt es auch davon abhängen ob PHP als Modul oder als CGI läuft
                Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
                Schön - etwas Geschichte kann ja nicht schaden.
                Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

                Kommentar


                • #9
                  Also das stimmt so nicht ganz was ich geschrieben hab - ein Bild, dass du im Speicher erzeugst ist kleiner und kann maximal 600x600 groß sein, was maximal ein ca. 1MB großes Bild im Speicher erzeugt. Damit solltest du eigentlich grad noch im Limit liegen...

                  Nochmal editiert, da falsche MB für 600x600 angegeben.
                  Zuletzt geändert von Quetschi; 27.10.2009, 13:38.
                  Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
                  Schön - etwas Geschichte kann ja nicht schaden.
                  Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

                  Kommentar


                  • #10
                    Hallo,

                    @Quetschi: Danke für die Erklärung, ich hab jetzt ein 11 MB Bild zum Testen hochgeladen und getimagesize gibt folgendes aus:

                    PHP-Code:
                    Array ( [0] => 2048 [1] => 1536 [2] => [3] => width="2048" height="1536" [bits] => [channels] => [mime] => image/jpeg 
                    Das sind dann wohl knapp 10 MB, dieses Bild geht jedenfalls ohne Probleme.

                    Kann es etwas mit der Kameraeinstellung zu tun haben? Sind das vielleicht RAW-Daten? Weil, warum ist eine Datei mit höherer Auflösung wesentlich kleiner?

                    Gruß
                    Michel

                    Kommentar


                    • #11
                      Hallo Michel,

                      Raw-Dateien sind etwas ganz anderes und haben mit JPEG nichts zu tun. JPEG-Dateien werden durch ein kompliziertes Verfahren kodiert und können daher bei gleicher Pixelanzahl sehr unterschiedliche Dateigrößen ergeben. Kontrastarme Bilder mit weichen Verläufen lassen sich z. B. sehr gut komprimieren, während detailreiche Bilder mit satten Farben und hohem Kontrast in der Regel etwas größere Dateien ergeben.

                      Gruß,

                      Amica
                      [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
                      Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
                      Super, danke!
                      [/COLOR]

                      Kommentar


                      • #12
                        Zitat von Lengen1971 Beitrag anzeigen
                        Sind das vielleicht RAW-Daten? Weil, warum ist eine Datei mit höherer Auflösung wesentlich kleiner?
                        Stichwort JPEG-Komprimierung - die Freundin der Nacht hat es ja im Prinzip schon erklärt.

                        Zusätzlich kann man noch erwähnen:
                        Du kannst das gleiche Bild mit gleichen Pixelmaßen (sagen wir mal 3000x2000) einmal mit geringer Komprimierung speichern, was die Qualität des Ausgangsbildes sehr gut erhält, aber mehr Platz auf der Festplatte einnimmt und du kannst das gleiche Bild einmal mit starker Komprimierung speichern, wodurch es wenig Platz auf der Festplatte verbraucht, die Bildqualität leidet dann jedoch darunter.

                        Ist aber alles völlig egal - wenn du Bilddaten mit PHP-Bordmitteln verarbeitest, zählt nur die Größe in Pixeln, die Anzahl der Kanäle und die Farbtiefe. Was die Datei als .jpg gespeichert auf der Platte belegt hat keinerlei Relevanz.
                        Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
                        Schön - etwas Geschichte kann ja nicht schaden.
                        Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

                        Kommentar


                        • #13
                          Hallo Quetschi und "FreundinDerNacht",

                          vielen Dank für eure Erklärungen, dann bleibt nur noch, die DigiCam auf weniger Pixel einzustellen, hierfür würde theoretisch ja 1 MegaPixel reichen.

                          Aber komisch ist es doch. Es sind beide sehr detailreiche Bilder mit hoher Qualität abgespeichert und trotzdem so ein riesen Größenunterschied... hm.

                          Wenn die Kamera RAW-Daten speichert und mein Kumpel sie direkt von der Speicherkarte auf den Computer kopiert, das hätte auch keine Auswirkung?

                          Danke
                          Gruß
                          Michael

                          Kommentar


                          • #14
                            Zitat von Lengen1971 Beitrag anzeigen
                            vielen Dank für eure Erklärungen, dann bleibt nur noch, die DigiCam auf weniger Pixel einzustellen, hierfür würde theoretisch ja 1 MegaPixel reichen.
                            Oder vor dem Upload auf den Server verkleinern!?
                            Zitat von Lengen1971 Beitrag anzeigen
                            Aber komisch ist es doch. Es sind beide sehr detailreiche Bilder mit hoher Qualität abgespeichert und trotzdem so ein riesen Größenunterschied... hm.
                            mh - um das zu beurteilen müsst ich die Bilder schon sehen - dennoch, die Größe als .jpg-Datei kann schon sehr unterschiedlich ausfallen (Bei verschiedenen Bilder mit gleicher Pixelgröße und gleicher Komprimierungseinstellung).
                            Zitat von Lengen1971 Beitrag anzeigen
                            Wenn die Kamera RAW-Daten speichert und mein Kumpel sie direkt von der Speicherkarte auf den Computer kopiert, das hätte auch keine Auswirkung?
                            Wie? RAW-Daten wirst du kaum oder gar nicht mit PHP verarbeitet bekommen. Keine Ahnung ob man den RAW-Codec da irgendwie reinbringen kann.
                            Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
                            Schön - etwas Geschichte kann ja nicht schaden.
                            Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

                            Kommentar


                            • #15
                              Hallo Quetschi,

                              ich stell dir die beiden Bilder mal zum Anschauen auf´n Server:

                              PA0801102.jpg <- dieses Bild (1,9 MB) geht nicht
                              FILE0269.JPG<- dieses Bild (13,2 MB) geht


                              @all: Vielen Dank für die vielen Hilfestellungen und die Geduld

                              Gruß
                              Michael

                              Kommentar

                              Lädt...
                              X