Hi there,

I have a system where a user can upload an image, once an image has been uploaded php crops the image and then resizes to to a thumbnail. This works perfectly well with JPEGs, but does not work with PNGs and GIFs.

I have used code to make sure the functions can deal with PNGs and GIFs but then the code runs all that is returned is an empty png or gif file and I do not know why. Here are my functions:

Function to solely resize the image:

function createthumb($name, $filename, $new_w, $new_h)
{
	$system = explode(".", $name);
	
	if (preg_match("/jpg|jpeg/", $system[1]))
	{
		$src_img=imagecreatefromjpeg($name);
	}
	if (preg_match("/png/", $system[1]))
	{
		$src_img = imagecreatefrompng($name);
	}
	if (preg_match("/gif/", $system[1]))
	{
		$src_img = imagecreatefromgif($name);
	}

	$old_x = imagesx($src_img);
	$old_y = imagesy($src_img);	
	
	$thumb_w = $new_w;
	$thumb_h = $new_h;	

	$dst_img = ImageCreateTrueColor($thumb_w, $thumb_h);
	
	imagecopyresampled($dst_img, $src_img, 0, 0, 0, 0, $thumb_w, $thumb_h, $old_x, $old_y); 
	
	if (preg_match("/png/", $system[1]))
	{
		imagepng($dst_img, $filename, 100); 
	} 
	else  if (preg_match("/gif/", $system[1]))
	{
		imagegif($dst_img, $filename, 100);
	}
	else
	{
		imagejpeg($dst_img, $filename, 100); 
	}
	
	imagedestroy($dst_img); 	
	imagedestroy($src_img); 
}

code to crop the image:

function createthumbcrop($name, $filename, $new_w, $new_h)
{
	$system = explode(".", $name);
	
	if (preg_match("/jpg|jpeg/", $system[1]))
	{
		$src_img=imagecreatefromjpeg($name);
	}
	if (preg_match("/png/", $system[1]))
	{
		$src_img = imagecreatefrompng($name);
		
	}
	if (preg_match("/gif/", $system[1]))
	{
		$src_img = imagecreatefromgif($name);
	}

	$old_x = imagesx($src_img);
	$old_y = imagesy($src_img);	
	
	if ($old_x > $old_y)
	{
		$width = ($old_x - $old_y) / 2;		
		$height = 0;
	}
	else if ($old_y > $old_x)
	{
		$width = 0;
		$height = ($old_y - $old_x) / 2;
	}
	else
	{
		$width = 0;
		$height = 0;
	}

	// New image size
	$thumb_w  = $new_w;
	$thumb_h = $new_h;

	// Starting point of crop
	$tlx = floor($old_x / 2) - floor($thumb_w / 2);
	$tly = floor($old_y / 2) - floor($thumb_h / 2);

	// Adjust crop size if the image is too small
	if ($tlx < 0)
	{
		$tlx = 0;
	}
	if ($tly < 0)
	{
		$tly = 0;
	}

	if (($old_x - $tlx) < $thumb_w)
	{
		$thumb_w = $old_x - $tlx;
	}
	if (($old_y - $tly) < $thumb_h)
	{
		$thumb_h = $old_y - $tly;
	}

	if ($old_x > $old_y)
	{
		$dst_img = imagecreatetruecolor($old_y, $old_y);
	}
	else if ($old_y > $old_x)
	{
		$dst_img = imagecreatetruecolor($old_x, $old_x);
	}
	else
	{
		$dst_img = imagecreatetruecolor($old_x, $old_y);
	}


	
	imagecopy($dst_img, $src_img, 0, 0, $width, $height, $old_x, $old_y);

/*
	$dst_img = ImageCreateTrueColor($thumb_w, $thumb_h);
	
	imagecopyresampled($dst_img, $src_img, 0, 0, 0, 0, $thumb_w, $thumb_h, $old_x, $old_y); 
*/	
	
	if (preg_match("/png/", $system[1]))
	{
		imagepng($dst_img, $filename, 100); 
	} 
	else  if (preg_match("/gif/", $system[1]))
	{
		imagegif($dst_img, $filename, 100);
	}
	else
	{
		imagejpeg($dst_img, $filename, 100); 
	}
	
	imagedestroy($dst_img); 	
	imagedestroy($src_img); 
}

I hope someone can help.

Thanks.

Dani AI

Generated

Two likely causes explain why JPEG thumbnails work but PNG/GIF results are empty: (1) the code does not preserve PNG alpha or GIF palette transparency when copying into a truecolor image, and (2) incorrect parameters are being passed to the output functions. 's suggestion to use a single loader (imagecreatefromstring on the file contents) is a good start because it avoids missed file-type branches, but transparency handling and some copy/save bugs still need to be fixed.

Key fixes to apply:

  • Detect extension robustly (use lowercased pathinfo or getimagesize/mime) instead of explode(".").
  • For PNG: disable alpha blending on the destination, enable saving alpha, and fill the canvas with a fully transparent color before copying.
  • For GIF: preserve the source transparent index (imagecolortransparent) or convert the truecolor result back to a 256-color palette with imagetruecolortopalette and set the transparent index.
  • Use imagecopyresampled for resampling. In the crop routine, ensure the source width/height arguments are the intended crop size (the original used full image dims in the copy call — that can produce wrong output).
  • Pass correct parameters when saving: imagepng uses a compression level 0..9 (omit or use a value in range); imagegif does not accept a quality parameter.

A compact example of the save/resample logic (illustrative, not a drop-in for the original functions):

# create $dst = imagecreatetruecolor($w,$h)
# for PNG:
imagealphablending($dst, false);
imagesavealpha($dst, true);
$trans = imagecolorallocatealpha($dst, 0,0,0,127);
imagefilledrectangle($dst, 0,0, $w, $h, $trans);

# for GIF with a transparent source:
$srcTrans = imagecolortransparent($src);
if ($srcTrans >= 0) {
  $c = imagecolorsforindex($src, $srcTrans);
  $t = imagecolorallocate($dst, $c['red'],$c['green'],$c['blue']);
  imagefill($dst, 0,0, $t);
  imagecolortransparent($dst, $t);
}

imagecopyresampled($dst, $src, 0,0, $sx,$sy, $dw,$dh, $sw,$sh);

# save:
imagepng($dst, $file, 6);   # compression 0-9
imagegif($dst, $file);      # no quality param

Quick checklist: confirm GD supports PNG/GIF via gd_info(), verify imagecreatefromstring() does not return false, fix any wrong width/height arguments in imagecopy calls, correct the imagepng/imagegif calls, and test with both paletted GIFs and 32-bit PNGs. Mentioning : the single-loader approach plus the transparency and save fixes above typically resolves the empty-output problem.

Recommended Answers

All 2 Replies

PHP has a function called 'imagecreatefromstring()';
It will let you create an image from a string regardless of the type so you don't have to keep checking for the file types.
Try something like

$src_image = imagecreatefromstring(file_get_contents($name));

You can even do error reporting

$src_image = imagecreatefromstring(file_get_contents($name))
if ( $src_image == false ) {
     die("Not a valid image");
}

From http://php.net/imagecreatefromstring
imagecreatefromstring() returns an image identifier representing the image obtained from the given data. These types will be automatically detected if your build of PHP supports them: JPEG, PNG, GIF, WBMP, and GD2.

If you try running that on a valid image and it returns false, it's likely your build of PHP was not compiled with support for that image type.
-Sam

Thanks for the reply, sorry it has taken me so long to get back to you.

This seems like it could work for me but I am unsure where i would put it into my code. I am guessing that it will replace part of the code but I am not sure if I would keep the if statement and just replace 'imagecreatefromjpeg' in each case with 'imagecreatefromstring' or if I would get rid of the if statement entirely and just use that.

Hope you can help.

Thanks very much

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.