| PHP Developer Forum Hier habt ihr die Möglichkeit, eure Skriptprobleme mit anderen Anwendern zu diskutieren. Seid so fair und beantwortet auch Fragen von anderen Anwendern. Dieses Forum ist sowohl für ANFÄNGER als auch für PHP-Profis! Post your PHP questions here! |
 |
|

23-10-2009, 12:21
|
|
Lengen1971
Registrierter Benutzer
|
|
Registriert seit: Oct 2003
Beiträge: 57
|
|
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:
Zitat:
|
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:
Zitat:
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
|

23-10-2009, 12:25
|
AmicaNoctis
 Moderatorin
|
|
Registriert seit: Jul 2009
Beiträge: 5.550
|
|
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
|

23-10-2009, 12:42
|
|
pekka
PHP Master
|
|
Registriert seit: Jun 2001
Ort: Köln
Beiträge: 6.608
|
|
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.
|

23-10-2009, 13:16
|
|
DonManfred
Registrierter Benutzer
|
|
Registriert seit: Nov 2003
Beiträge: 80
|
|
Zitat:
Zitat von Lengen1971
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 = ImageCreateTrueColor( 2000, 2000);
echo GetMem('vor ImageDestroy() bei ImageCreateTrueColor');
ImageDestroy($image);
echo GetMem('nach ImageDestroy() bei ImageCreateTrueColor');
$image = ImageCreate( 2000, 2000);
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...
|

27-10-2009, 12:06
|
|
Lengen1971
Registrierter Benutzer
|
|
Registriert seit: Oct 2003
Beiträge: 57
|
|
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==0 || $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] => 2 [3] => width="3264" height="2448" [bits] => 8 [channels] => 3 [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�gbar: 40M
Danke für alle Hinweise und Tips.
Gruß
Michael
|

27-10-2009, 12:32
|
|
pekka
PHP Master
|
|
Registriert seit: Jun 2001
Ort: Köln
Beiträge: 6.608
|
|
Vielleicht erlaubt dein Provider ImageMagick-Aufrufe? IM läuft m.W. immer außerhalb der Skripteigenen RAM-Beschränkungen.
|

27-10-2009, 12:37
|
|
Quetschi
PHP Expert
|
|
Registriert seit: Dec 2004
Beiträge: 2.759
|
|
Zitat:
|
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.
Geändert von Quetschi (27-10-2009 um 13:05 Uhr)
|

27-10-2009, 12:39
|
|
Quetschi
PHP Expert
|
|
Registriert seit: Dec 2004
Beiträge: 2.759
|
|
Zitat:
Zitat von pekka
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
|

27-10-2009, 12:43
|
|
Quetschi
PHP Expert
|
|
Registriert seit: Dec 2004
Beiträge: 2.759
|
|
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.
Geändert von Quetschi (27-10-2009 um 13:38 Uhr)
|

27-10-2009, 13:56
|
|
Lengen1971
Registrierter Benutzer
|
|
Registriert seit: Oct 2003
Beiträge: 57
|
|
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] => 2 [3] => width="2048" height="1536" [bits] => 8 [channels] => 3 [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
|

27-10-2009, 14:05
|
AmicaNoctis
 Moderatorin
|
|
Registriert seit: Jul 2009
Beiträge: 5.550
|
|
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
|

27-10-2009, 14:23
|
|
Quetschi
PHP Expert
|
|
Registriert seit: Dec 2004
Beiträge: 2.759
|
|
Zitat:
Zitat von Lengen1971
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.
|

27-10-2009, 14:27
|
|
Lengen1971
Registrierter Benutzer
|
|
Registriert seit: Oct 2003
Beiträge: 57
|
|
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
|

27-10-2009, 14:38
|
|
Quetschi
PHP Expert
|
|
Registriert seit: Dec 2004
Beiträge: 2.759
|
|
Zitat:
Zitat von Lengen1971
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:
Zitat von Lengen1971
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:
Zitat von Lengen1971
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.
|

27-10-2009, 14:57
|
|
Lengen1971
Registrierter Benutzer
|
|
Registriert seit: Oct 2003
Beiträge: 57
|
|
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
|
|
Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
|
|
|
| Themen-Optionen |
|
|
| Thema bewerten |
|
|
Forumregeln
|
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.
HTML-Code ist aus.
|
|
|
|
PHP News
|