Hi All.

I am having a nightmare with a script that allows customers to upload image files to use in designing their own t-shirts, etc with a maximum size of 3000 x 3000 pixels. The script takes their original uploaded image and creates a medium sized thumbnail, and a small thumbnail. The script works fine for JPG and GIF files up to the maximum allowed size (3000x3000). If the customer uploads a larg-ish PNG file (greater than roughly 1500 x 1500 pixels) the script dies with an Internal Error 500 at the point I call the GD function imagecreatefrompng() to create a thumbnail of the image.

I have done all of the obvious thing like increasing the PHP memory limit (which is now set to 128M). My host has confirmed that they do restrict memory usage on the Apache side of things too but they have upped my allowed memory to around 90MB for testing but the problem persists. When I use memory_get usage() just before the imagecreatefrompng it reports memory usage as around 4MB. According to the forumlae I have seen around the net I have calculated that I should only need around 20MB of RAM to open a PNG image of 3000 x 3000 pixels.

Is there something else I can do to get this working or am I faced with some sort of PHP/GD bug?

Server specs:
5.1.6 (Zend: 2.1.0)
Apache/2.2.3 (Fedora)
MySQL 5.0.27
GD version: bundled (2.0.28 compatible)

The area in the script where the error occurs looks like this:

$extension = substr($file_details['name'], strrpos($file_details['name'], '.') + 1);
if ($extension == 'jpg' || $extension == 'jpeg' || $extension == 'png' || $extension == 'gif'){
	if (!file_exists($uploads_dir_path_med.'/'.$large_prefix.$file_details['name'])){
		if ($extension == 'jpg' || $extension == 'jpeg'){
			$image = imagecreatefromjpeg($uploads_dir_path_lrg.'/'.$file_details['name']);
			$image_width = imagesx($image);
			$image_height = imagesy ($image);
		}
		else if ($extension == 'png'){
			list($image_width, $image_height) = getimagesize($uploads_dir_path_lrg.'/'.$file_details['name']);
//script dies with error 500 at the next line
			$image = imagecreatefrompng($uploads_dir_path_lrg.'/'.$file_details['name']);
		}
		else if ($extension == 'gif'){
			$image = imagecreatefromgif($uploads_dir_path_lrg.'/'.$file_details['name']);
			$image_width = imagesx($image);
			$image_height = imagesy ($image);
		}
		$maxwidth = 200;
		$maxheight = 200;

	$x_ratio = $maxwidth / $image_width;
	$y_ratio = $maxheight / $image_height;

	if( ($image_width <= $maxwidth) && ($image_height <= $maxheight) ){
		$tn_width = $image_width;
		$tn_height = $image_height;
	}
	elseif (($x_ratio * $image_height) < $maxheight){
		$tn_height = ceil($x_ratio * $image_height);
		$tn_width = $maxwidth;
	}
	else{
		$tn_width = ceil($y_ratio * $image_width);
		$tn_height = $maxheight;
	}

	$output = imagecreatetruecolor ($tn_width, $tn_height);
	imagealphablending($output, false);
	imagecopyresampled ($output,$image,0,0,0,0,$tn_width, $tn_height,$image_width,$image_height);
	imagesavealpha($output, true);
	if ($extension == 'jpg'){
		imagejpeg($output,$uploads_dir_path_med.'/'.$large_prefix.$file_details['name']);
	}
	else if ($extension == 'png'){
		imagepng($output,$uploads_dir_path_med.'/'.$large_prefix.$file_details['name']);
	}
	else if ($extension == 'gif'){
		imagegif($output,$uploads_dir_path_med.'/'.$large_prefix.$file_details['name']);
	}
	imagedestroy ($image);
	imagedestroy ($output);
}
if (!file_exists($uploads_dir_path_thmb.'/'.$thmb_prefix.$file_details['name'])){
	if ($extension == 'jpg' || $extension == 'jpeg'){
		$image = imagecreatefromjpeg($uploads_dir_path_med.'/'.$large_prefix.$file_details['name']);
	}
	else if ($extension == 'png'){
		$image = imagecreatefrompng($uploads_dir_path_med.'/'.$large_prefix.$file_details['name']);
	}
	else if ($extension == 'gif'){
		$image = imagecreatefromgif($uploads_dir_path_med.'/'.$large_prefix.$file_details['name']);
	}
	$maxwidth = 69;
	$maxheight = 90;
	$image_width = imagesx($image);
	$image_height = imagesy ($image);

	$x_ratio = $maxwidth / $image_width;
	$y_ratio = $maxheight / $image_height;

	$x_ratio = $maxwidth / $image_width;
	$y_ratio = $maxheight / $image_height;

	if( ($image_width <= $maxwidth) && ($image_height <= $maxheight) ){
		$tn_width = $image_width;
		$tn_height = $image_height;
	}
	elseif (($x_ratio * $image_height) < $maxheight){
		$tn_height = ceil($x_ratio * $image_height);
		$tn_width = $maxwidth;
	}
	else{
		$tn_width = ceil($y_ratio * $image_width);
		$tn_height = $maxheight;
	}
	$output = imagecreatetruecolor ($tn_width, $tn_height);
	$grey = imagecolorallocate($output,128,128,128);
	imagefilledrectangle($output, 0, 0, $tn_width, $tn_height, $grey);
	imagecopyresampled ($output,$image,0,0,0,0,$tn_width, $tn_height,$image_width,$image_height);
	$output_final = imagecreatetruecolor (69, 90);
	$white = imagecolorallocate($output_final,255,255,255);
	imagefilledrectangle($output_final, 0, 0, 69, 90, $white);
	imagecopy ($output_final,$output,(69/2)-($tn_width/2),(90/2)-($tn_height/2),0,0,$tn_width, $tn_height);
	if ($extension == 'jpg'){
		imagejpeg($output_final,$uploads_dir_path_thmb.'/'.$thmb_prefix.$file_details['name']);
	}
	else if ($extension == 'png'){
		imagepng($output_final,$uploads_dir_path_thmb.'/'.$thmb_prefix.$file_details['name']);
	}
	else if ($extension == 'gif'){
		imagegif($output_final,$uploads_dir_path_thmb.'/'.$thmb_prefix.$file_details['name']);
	}
	imagedestroy ($image);
	imagedestroy ($output);
	imagedestroy ($output_final);
}
//add image details to DB
$sql = "
	INSERT INTO cd_user_uploaded_images (customer_id,image_filename,image_width,image_height,no_of_colours,date_added,mime_type,undersize)
	VALUES ('".$_SESSION['customer_id']."','".$file_details['name']."','".(int)$file_details['width']."','".(int)$file_details['height']."','no_colors',NOW(),'".$file_details['type']."','".(int)$undersize."')
";
$db->Execute($sql);
}
header( "Location: ".HTTP_SERVER. "/index.php?main_page=custom_designer&products_id=".$products_id."&is=u&ht=0".$size_warn."&scs=1");
exit();

Any help or advise would be greatly appreciated as I have run out of ideas now....

Thanks.

    I forgot to add the errors being logged in the apache raw log files when the error 500 occurs:

    [Tue Aug 28 13:55:25 2007] [error] [client 121.11.11.11] FATAL:  emalloc():  Unable to allocate 25380000 bytes, referer: http://www.website.com/index.php?main_page=custom_designer&products_id=17&um=1
    [Tue Aug 28 13:55:25 2007] [error] [client 121.11.11.11] Premature end of script headers: php-script, referer: http://www.website.com/index.php?main_page=custom_designer&products_id=17&um=1
    

      I have solved this problem and thought I would leave the answer here in case someone else has a similar issue.

      It seems that with the setup this server is running opening a PNG image with imagecreatefrompng that is 3000 x 3000 pixels requires at least 128MB of memory to open. The reason I was getting the internal error 500 was that my php.ini file was set to 128M but the hosting company had applied memory limits of 32MB on the Apache side of things. They have increased this to 128MB and this has resolved the issue for me. They had said before that they had increased my memory allowance on Apache but in fact had not. When a second support person checked it was still set to 32MB in Apache.

      The part I still find confusing is that imagecreatefromjpeg and imagecreatefromgif were both happy and functional with 32MB of memory but imagecreatefrompng wanted 128MB to open an image of the same pixel size. Pretty weird if you ask me 😕

      I am just happy that I got it working!

        Write a Reply...