PHP Bilder verkleinern problem...

Stevenking

Well-known member
ID: 19802
L
4 Mai 2006
88
7
Hallo zusammen

Hab ein Problem mit einem teil des scripts...
und zwar wird beim hochladen eines Bildes, geguckt wie groß das Bild ist.
ist es größer als eine festgelegt Größe 200kb dann gibt er

$image_too_big == 1 aus

macht er auch alles bis zu einer bestimmt größe...
nur wenn die Datei größer als 1MB wird gibt es probleme.

Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 3200 bytes) in /usr/virtualweb/write_ad.php on line 296

memory_limit ist 32 MB


PHP:
if ( $image_too_big == 1) {
				
					switch ($af_size[2]) {
					case 1 : $src = ImageCreateFromGif( $af_dir_ads.$adid.$itrail.".".$thispicext); break;
					case 2 : $src = ImageCreateFromJpeg( $af_dir_ads.$adid.$itrail.".".$thispicext); break;
					case 3 : $src = ImageCreateFromPng( $af_dir_ads.$adid.$itrail.".".$thispicext); break;
					}

					$width_before  = ImageSx( $src);
					$height_before = ImageSy( $src);

					if ( $width_before  >= $height_before) {
					$width_new = min(800, $width_before);
					$scale = $width_before / $height_before;
					$height_new = round( $width_new / $scale);
					}
					else {
					$height_new = min(600, $height_before);
					$scale = $height_before / $width_before;
					$width_new = round( $height_new / $scale);
					}

					$dst = ImageCreateTrueColor( $width_new, $height_new);

					// GD Lib 2
					ImageCopyResampled( $dst, $src, 0, 0, 0, 0, $width_new, $height_new, $width_before, $height_before);

					// GD Lib 1
					//ImageCopyResized( $dst, $src, 0, 0, 0, 0, $width_new, $height_new, $width_before, $height_before);

					switch ($af_size[2]) {
					case 1 : ImageGIF( $dst, $af_dir_ads.$adid.$itrail.".".$thispicext); break;
					case 2 : ImageJPEG( $dst, $af_dir_ads.$adid.$itrail.".".$thispicext); break;
					case 3 : ImagePNG( $dst, $af_dir_ads.$adid.$itrail.".".$thispicext); break;
					}

					imagedestroy( $dst);
					imagedestroy( $src);
				}

Ich denke das es an ImageCopyResampled liegt...
er macht ja im klassichen Sinne keine kopie sondern umschreibt das alte Bild...

kennt vielleicht jemand eine bessere möglichkeit?
Was ich festgestellt hab ist, wenn ich denn block rausnehme, hab ich keine Probleme. dann läd er auch Bilder mit 5 MB hoch...

Oder kann ich den teil das Scripts nicht zweimal ausführen?
Weil hab gleich darunter noch mal das ganze für ein Thumbnail. Nur da benennt er das Bild neu... komisch ist das er es immer macht, egal ob das Bild 5MB oder 100KB groß ist.
 
Wenn du imagedestroy() machst, wird der Speicher wieder frei gemacht. Du musst nur drauf achten, dass der aktuell belegte Speicher nicht über dem memory_limit liegt.

Wenn du vorher schon 31MB durch Variablen und Zeugs belegt hast und dann 2MB für ein Bild anforderst, bist du auch drüber.
 
PHP belegt sicher nicht nur 31 MB sondern mehr.
die max begrenzung bezieht sich auf eine speicherreservierung !
Wer natürlich keinen Speicher wieder frei gibt (ist so in jeder programmiersprache) dann ist der speicher irgendwann voll.

Kann leider zu dem Resample nichts genaueres sagen, weil ich immer nur kleinere Bilder her hatte als 1MB oder mehr.

Aber hier mal zu Deinem Problem:
https://bugs.php.net/bug.php?id=45030
 
Hallo

Also das mit dem imagedestroy() hab ich doch drin...
der speicher wird da wieder freigegeben.
aber er kommt ja gar nicht soweit...

kann es vielleicht an ner zeit Überschreidung liegen?
das das PHP scirpt zu lange läuft und deswegen die fehlermeldung kommt?
 
kann es vielleicht an ner zeit Überschreidung liegen?
das das PHP scirpt zu lange läuft und deswegen die fehlermeldung kommt?
Dann würdest du die Fehlermeldung kriegen, dass die Zeit überschritten wurde ;) PHP denkt sich bei Zeitüberschreitung keine abenteuerliche Story aus, dass du 3200 Bytes Speicher anfordern wolltest :ugly:
 
du brauchst nicht vermuten, die Meldung sagt genau, dass bei der (den) Operation(en) in Zeile 296 der Fehler auftritt, also wird es auch genau ein Kommando in dieser Zeile sein.
Solange du uns nicht sagst, was die Zeile 296 ist, kann man dir nicht helfen.
 
Hallo

sorry hab ganz vergessen euch die Zeit zu markieren...
es ist die Zeile
PHP:
ImageCopyResampled( $dst, $src, 0, 0, 0, 0, $width_new, $height_new, $width_before, $height_before);

ist im dem Teilscript die 26...

zeit überschreitung war es nicht, weil hab von 30 auf 60 sec. geändert und hat sich nicht geändert an der Fehlermeldung...
 
Die Lösung ist doch einfach: höheres memory_limit setzen. Dein Code sieht mir nicht danach aus, als könnte man noch viel daran optimieren.

Das Problem liegt einfach daran, dass die Bilder für die GD-Lib unkomprimiert im Speicher liegen und es auch noch Overhead gibt. Daher kommt es, dass das ganze so viel Speicher braucht.
 
Ist doch klar, dass der Speicher dir da um die Ohren fliegt.

Ein Bild mit der Größe von 200 Pixeln mal 300 Pixeln benötigt 200 * 300 * 4 Byte.
3 Byte für die Farben Rot, Grün und Blau sowie nochmal 1 Byte für die 256 Transparenzstufen.

Dann hast du 2 Bilder im Speicher $src und $dst, die Operation imagecopyresampled benötigt dann für die Berechnungen eben auch noch einmal selbst Arbeitsspeicher und das reicht dann eben nicht mehr aus.

Also entweder setzt du das memory_limit hoch oder schreibst einen eigenen Algorithmus der korrekt Bilder skalieren kann auf Basis des primitiven Zugriffs der Farbe eines einzelnen Pixels, das wird jedoch unendlich langsam sein und auf keinen Fall speicherschonender als die angebotene Version der gdlibrary.
Also hast du effektiv doch nur eine Möglichkeit :biggrin:
 
Okay... werde ich mal ausprobieren...

sag ich heute Abend bescheid wenn ich wieder Zuhause bin ob es geholfen hat.

MFG
Steve
 
weiß jemand warum
ini_set("memory_limit", "128M") ; nicht geht das bleibt dann 32 MB
wenn ich aber
ini_set("memory_limit", "28M") ; eingeben werden er auch 28 MB

ich will das nicht in php.ini bei mir ändern...
gibts da nen trick wie ich das einstellen kann, ohne denn Wert in PHP.ini für alle seiten zu ändern?
 
na mit dem ersten Befehlt versucht das memory_limit höher zu setzen, was du scheinbar nicht darfst, deshalb geht es nicht.
Mit dem 2. Befehl setzt du dein memory_limit aber kleiner als bisher, das darfst du natürlich.
 
ja...
aber ich muss doch nur in dem einen PHP script den speicher hochsetzen...
deswegen wollte ich das mit ini_set machen kann man nicht in PHP.ini einstellen das ich mit ini_set auch den aktuellen wert erhöhen darf?
oder ich muss mal gucken das ich das in meinem Vhost vielleicht einfach hochsetze... dann sind auch nicht alle anderen abtroffen
 
Kannst Du shell-Befehle absetzen und Software auf der Maschine installieren? Wenn ja nutz imagemagick.

Da es an der Shell läuft, werden auch kaum die für PHP reservierten verschwendet. Es gibt auch eine PHP-Erweiterung bei der ich allerdings nichts zu den Resourcen sagen kann - nie verwendet.

Nutz ich bei mir auch für Größenanpassung und Thumbnails in ein paar wenigen Zeilen ohne Rücksicht auf das Bild- und Dateiformat nehmen zu müssen...

Gruß