[PHP] Miniaturki zdjec i za malo pamieci

0

Witam.

Mam funkcje robienia miniaturek zdjec w php korzystajaca z ImageCreateTrueColor, ImageCopyResampled i imagejpeg. Nie jest to moja funkcja, tylko poprzednika tworzacego czesc serwisu i nie chce mi sie za bardzo jej zmieniac. Uploadowane zdjecia maja rozmiar do 500kB. Problem w tym, ze niektore z nich powoduje wyczerpanie pamieci i pojawienie sie takiego bledu:

Fatal error: Allowed memory size of 20971520 bytes exhausted (tried to allocate 6684 bytes) in ...

Ma ktos pomysl jak zrobic inaczej? Swoja droga czy imagecopyresampled i imagecopyresized az tak bardzo sie roznia?

pozdrawiam
johny

0

Sprobuj tego

(ja jestem zwolennikiem do zapisu miniatur do pliku - katalog tn, jednak bez problemu mozesz to przekierowac do skryptu)

function MakeTNEx($fname,$Image,$MaxSize){
  $filename = sprintf("%s/%s",$fname,$Image);
  $filename1 = sprintf("%s/tn/tn_%s",$fname,$Image);  
  if (file_exists($filename1)) return;
  if  (!file_exists("$fname/tn")) mkdir ("$fname/tn", 0777);
  $im = imagecreatefromjpeg($filename);
  $w = imageSX($im);
  $h = ImageSY($im);  
  if ($w > $h) 
  {
   $nw = $MaxSize;
   $nh = $h*$nw/$w;
  }else {
   $nh = $MaxSize;
   $nw = $w*$nh/$h;
  }  
  $im1 = imagecreatetruecolor($nw,$nh);
  ImageCopyResized($im1,$im,0,0,0,0,$nw,$nh,$w,$h);
  ImageJpeg($im1,$filename1);
  ImageDestroy($im);
  ImageDestroy($im1);    
} 

czasami z brakiem pamieci (nie na wszystkich serwerach) spotykalem sie gdy chcialem na raz otworzyc
dwa duze pliki-obrazki. Moze w tym skrypcie nie zamykasz uchwytow > ImageDestroy?

ps. co do jakosci

Swoja droga czy imagecopyresampled i imagecopyresized az tak bardzo sie roznia?

to z funkcja imagecopyresized uzyskiwalem dobre rezultaty no ale mozna poprobowac.

0

W sumie jest tak samo, tylko z imageCopyResampled, a nie resized. Sprawdze, moze jest mniej pamieciozerne...

Ja tez jestem zwolennikiem zapisu, ta funkcje wlasnie przerobilem, zeby zapisywala, a nie generowala za kazdym razem - tym bardziej, ze wtedy blad pokazywal sie uzytkownikom :/

//edit
Brakowalo jednego ImageDestroy to raz, a po drugie uzylem skryptu z php.net:

  $info=getimagesize($file);
		
	$MB = Pow(1024,2);  // number of bytes in 1M
	$K64 = Pow(2,16);    // number of bytes in 64K
	$TWEAKFACTOR = 1.8;  // Or whatever works for you
	$memoryNeeded = round( ( $info[0] * $info[1]
	                                       * $info['bits']
	                                       * $info['channels'] / 8
	                         + $K64
	                       ) * $TWEAKFACTOR
	                     );
	$memoryHave = memory_get_usage();
	$memoryLimitMB = (integer) ini_get('memory_limit');
	$memoryLimit = $memoryLimitMB * $MB;

	if ( function_exists('memory_get_usage')
	     && $memoryHave + $memoryNeeded > $memoryLimit
	   ) {
	   $newLimit = $memoryLimitMB + ceil( ( $memoryHave
	                                     + $memoryNeeded
	                                     - $memoryLimit
	                                     ) / $MB
	                                   );
	   ini_set( 'memory_limit', $newLimit . 'M' );
	}

Po 4 roznych duzych plikach blad nie wyskakuje (zazwyczaj bylo po jednym), wiec chyba dziala.

Dzieki za pomoc :)

pozdrawiam
johny

1 użytkowników online, w tym zalogowanych: 0, gości: 1