Jump to content

GD Library Question


ColdEdge

Recommended Posts

Ok, so I have a code it works, but there is one little problem.... The script adds black bg to all PNG images uploaded that are renders or do not have a bg, I want my script to close a blind eye on this. And when creating a thumb and profile pic from a single image to leave it as it is.here is the script

function createThumbnail($new_file) {    	require 'config.php'; 	  	if(preg_match('/[.](jpg)$/', $new_file)) {  		$im = imagecreatefromjpeg($path_to_image_directory . $new_file);  	} else if (preg_match('/[.](gif)$/', $new_file)) {  		$im = imagecreatefromgif($path_to_image_directory . $new_file);  	} else if (preg_match('/[.](png)$/', $new_file)) {  		$im = imagecreatefrompng($path_to_image_directory . $new_file);  	}    	$ox = imagesx($im);  	$oy = imagesy($im);    	$nx = $final_width_of_image;  	$ny = floor($oy * ($final_width_of_image / $ox));    	$nm = imagecreatetruecolor($nx, $ny);    	imagecopyresampled($nm, $im, 0,0,0,0,$nx,$ny,$ox,$oy);    	if(!file_exists($path_to_thumbs_directory)) {  	  if(!mkdir($path_to_thumbs_directory)) {  		   die("There was a problem. Please try again!");  	  }  	   }    	imagejpeg($nm, $path_to_thumbs_directory . "medium_". $new_file, 1000);		$t = time();			$tn = '<img src="' . $path_to_thumbs_directory . "medium_" . $new_file . "?v=" . $t .'" alt="image" />';  	# $tn .= '<br />Congratulations. Your file has been successfully uploaded, and a thumbnail has been created.';  	echo $tn;  }  function createDisplaypic($new_file) {    	require 'config.php'; 	  	if(preg_match('/[.](jpg)$/', $new_file)) {  		$im = imagecreatefromjpeg($path_to_image_directory . $new_file);  	} else if (preg_match('/[.](gif)$/', $new_file)) {  		$im = imagecreatefromgif($path_to_image_directory . $new_file);  	} else if (preg_match('/[.](png)$/', $new_file)) {  		$im = imagecreatefrompng($path_to_image_directory . $new_file);  	}    	$ox = imagesx($im);  	$oy = imagesy($im);    	$nx = $final_width_of_dp;  	$ny = floor($oy * ($final_width_of_dp / $ox));    	$nm = imagecreatetruecolor($nx, $ny);    	imagecopyresampled($nm, $im, 0,0,0,0,$nx,$ny,$ox,$oy);    	if(!file_exists($path_to_dp_directory)) {  	  if(!mkdir($path_to_dp_directory)) {  		   die("There was a problem. Please try again!");  	  }  	   }    	imagejpeg($nm, $path_to_dp_directory . "large_". $new_file, 200);}

Link to comment
Share on other sites

This is the function I use to create thumbnails, it supports transparency for PNG and GIF images.

function resize_image($opts){  $src = isset($opts['source']) ? $opts['source'] : '';  $dest = isset($opts['dest']) ? $opts['dest'] : '';  $w = isset($opts['w']) ? intval($opts['w']) : 0;  $h = isset($opts['h']) ? intval($opts['h']) : 0;    if ($src == '')  {	return;  }  if ($w == 0 && $h == 0)  {	return;  }  if ($dest == '')	$dest = $src; // resize in place  // open the image  $ext = strtolower(array_pop(explode('.', $src)));  switch ($ext)  {	case 'jpg':	case 'jpeg':	  $i = imagecreatefromjpeg($src);	break;	case 'gif':	  $i = imagecreatefromgif($src);	break;	case 'png':	  $i = imagecreatefrompng($src);	break;	default:	  return;  }  $new_w = imagesx($i);  $new_h = imagesy($i);  if (($w != 0 && $new_w <= $w && $h == 0) ||	  ($w == 0 && $h != 0 && $new_h <= $h) ||	  ($w != 0 && $new_w <= $w && $h != 0 && $new_h <= $h))  {	// image is small enough	if ($dest != $src)	  copy($src, $dest);	return;  }  // determine new size  if ($w != 0 && $new_w > $w)  {	$new_h = ($w / $new_w) * $new_h;	$new_w = $w;  }  if ($h != 0 && $new_h > $h)  {	$new_w = ($h / $new_h) * $new_w;	$new_h = $h;  }    // resize  $new = imagecreatetruecolor($new_w, $new_h);    if ($ext == 'png' || $ext == 'gif')  {	$trnprt_indx = imagecolortransparent($i);	// If we have a specific transparent color	if ($trnprt_indx >= 0) 	{	  // Get the original image's transparent color's RGB values	  $trnprt_color = imagecolorsforindex($i, $trnprt_indx);	  // Allocate the same color in the new image resource	  $trnprt_indx = imagecolorallocate($new, $trnprt_color['red'], $trnprt_color['green'], $trnprt_color['blue']);	  // Completely fill the background of the new image with allocated color.	  imagefill($new, 0, 0, $trnprt_indx);	  // Set the background color for new image to transparent	  imagecolortransparent($new, $trnprt_indx);	}	// Always make a transparent background color for PNGs that don't have one allocated already	elseif ($ext == 'png')	{	  // Turn off transparency blending (temporarily)	  imagealphablending($new, false);	  // Create a new transparent color for image	  $color = imagecolorallocatealpha($new, 0, 0, 0, 127);	  // Completely fill the background of the new image with allocated color.	  imagefill($new, 0, 0, $color);	  // Restore transparency blending	  imagesavealpha($new, true);	}  }  imagecopyresampled($new, $i, 0, 0, 0, 0, $new_w, $new_h, imagesx($i), imagesy($i));  imagedestroy($i);  // save the image  switch ($ext)  {	case 'jpg':	case 'jpeg':	  imagejpeg($new, $dest);	break;	case 'gif':	  imagegif($new, $dest);	break;	case 'png':	  imagepng($new, $dest);	break;  }  imagedestroy($new);}

e.g.:

// resize big.png to max 100x100, save as small.pngresize_image(array(  'source' => 'big.png',  'dest' => 'small.png',  'w' => 100,  'h' => 100));// resize image.png to a max of 150px wide, overwrite original fileresize_image(array(  'source' => 'image.png',  'w' => 150));

That function will only make images smaller, it will not resize larger. The width and the height are the maximum values you want for each dimension. If the width and height are both set to 100, and the image that's uploaded is 400x800, then first it will resize the width to match what you told it, so that the image is now 100x200. Then it will look at the height, since the height is larger than the max height it will resize it again and make it 50x100, which fits the 100x100 max size. If you leave out the destination filename it will overwrite the original image. If you leave out both the width and height it won't do anything, you need to give it either a width or height, or both, plus a source filename, as a minimum.

Link to comment
Share on other sites

Ahey, I tried your script could not have merged it with mine.... a dammhere is the script from profile.php script

if($_GET['act'] == 'picture') {		$uid = $_SESSION['user_id'];  if(isset($_FILES['photo'])) {    	if(preg_match('/[.](jpg)|(gif)|(png)$/', $_FILES['photo']['name'])) {    		$filename = $_FILES['photo']['name']; 	 		$ext = array_pop(explode('.', $_FILES['photo']['name']));		$new_file = "t-" . ($uid) . "." .($ext);		$source = $_FILES['photo']['tmp_name'];  		$target = $path_to_image_directory . $new_file;  		$thumb = $path_to_thumbs_directory . "medium_" . $new_file . "?v=" . $t;		$dp = $path_to_dp_directory . "large_" . $new_file . "?v=" . $t;  		move_uploaded_file($source, $target);    		createThumbnail($new_file);		createDisplaypic($new_file);		  	}  		mysql_query("UPDATE users SET user_avatar = '".$target."', user_thumb = '".$thumb."', user_photo = '".$dp."' WHERE user_id = '".mysql_real_escape_string($_REQUEST['uid'])."'");}  		if($_SERVER['REQUEST_METHOD'] != 'POST')	{	$si = ("SELECT user_thumb FROM users WHERE user_id = '".$_SESSION['user_id']."'");	$sql = mysql_query($si);	if(!$sql)			{				echo '<div style="padding:8px;background-color:#fae3e3;border:2px solid #b25959;color:#313131;">Error!</div>';			}			else			{						while($row = mysql_fetch_assoc($sql))				{		echo '<form enctype="multipart/form-data" action="'.$_SERVER['PHP_SELF'].'?act=picture&m=1" method="post">';  		echo "<input type='hidden' value='".$_SESSION['user_id']."' name='uid'>";		echo '<input type="file" class="inputfile" size="30" id="photo" name="photo"/>';		echo '<input type="submit" class="inputsubmit" id="submit" name="submit" value="Update Photo"/>';		echo '<input type="button" class="inputsubmit" id="cancel" name="cancel" value="Cancel"/>';	echo '</form>'; 	}	}		}	echo'

the create new files are processed truth this two commandscreateThumbnail($new_file);createDisplaypic($new_file); O, yes one more thing as you can see in the form field the user is pointed to &m=1 which echos a message. How can I make it so when users clicks Update Photo, PHP can echo either like "Your picture was updated and saved! You might need to refresh the page few times to see the new picture." or an error message noting user that the file has not been saved. Without having to use

if($_GET['m'] == '1') {	echo '<div style="padding:5px;background-color:#fffceb;border:1px solid #b7b7b7;color:#313131;width:690px;">	Your picture was updated and saved! You might need to refresh the page few times to see the new picture.	</div>';	echo '<meta http-equiv="Refresh"content="5;url=profile.php?v='.$t.'">';	echo '<br/>';	}

Link to comment
Share on other sites

You may want to update your file upload script. You're not checking for upload errors, for example. This is another function I use to help with uploaded files:

function handle_file_upload($options){  $input = !empty($options['input']) ? $options['input'] : trigger_error('handle_file_upload: No input name specified', E_USER_ERROR);  $dest = !empty($options['dest_dir']) ? $options['dest_dir'] : trigger_error('handle_file_upload: No destination directory specified', E_USER_ERROR);  $dest_fname = !empty($options['dest_fname']) ? $options['dest_fname'] : '';  $overwrite = !empty($options['overwrite']) ? $options['overwrite'] : false;  $mode = !empty($options['mode']) ? $options['mode'] : false;  $allowed_ext = isset($options['allowed_ext']) && is_array($options['allowed_ext']) ? $options['allowed_ext'] : false;  if (!is_dir($dest))	trigger_error('handle_file_upload: Destination directory does not exist', E_USER_ERROR);  if (!isset($_FILES[$input]))	trigger_error('handle_file_upload: The input file was not found', E_USER_ERROR);  if ($_FILES[$input]['error'] > 0)  {	switch ($_FILES[$input]['error'])	{	  case 1:	  case 2; return array('success' => false, 'error' => 'The uploaded file was too large.');	  case 3: return array('success' => false, 'error' => 'The uploaded file was only partially received.');	  case 4: return array('success' => false, 'error' => 'No file was uploaded.');	  case 6: return array('success' => false, 'error' => 'Missing temporary folder.');	  case 7: return array('success' => false, 'error' => 'Failed to write file to disk.');	  case 8: return array('success' => false, 'error' => 'Invalid extension.');	}  }    if ($allowed_ext != false && !in_array(strtolower(array_pop(explode('.', $_FILES[$input]['name']))), $allowed_ext))	return array('success' => false, 'error' => 'That file type was not allowed.  Allowed types: ' . implode(', ', $allowed_ext));  if ($dest_fname != '')	$_FILES[$input]['name'] = $dest_fname;  $_FILES[$input]['name'] = strtolower(basename($_FILES[$input]['name']));  if (!$overwrite)  {	$fname = $_FILES[$input]['name'];	if (file_exists($dest . DIRECTORY_SEPARATOR . $fname))	{	  $chunks = explode('.', $fname);	  $ext = array_pop($chunks);	  $fname = implode('.', $chunks);	  $nr = 1;	  while (file_exists($dest . DIRECTORY_SEPARATOR . $fname . '.' . $ext))		$fname = $fname . '.' . $nr++;	  $_FILES[$input]['name'] = $fname . '.' . $ext;	}  }  $target = $dest . DIRECTORY_SEPARATOR . $_FILES[$input]['name'];  if (!move_uploaded_file($_FILES[$input]['tmp_name'], $target))	return array('success' => false, 'error' => 'The uploaded file could not be moved.');  if ($mode !== false)	chmod($target, $mode);  return array('success' => true, 'name' => $_FILES[$input]['name']);}

e.g.:

$file = handle_file_upload(array(  'input' => 'photo',  'dest_dir' => $path_to_image_directory,  'dest_fname' => $new_file,  'overwrite' => false,  'mode' => 0644,  'allowed_ext' => array('jpg', 'png', 'gif')  ));if ($file['success']){  echo 'the file was uploaded and saved as ' . $file['name'];}else{  echo 'upload error: ' . $file['error'];}

How can I make it so when users clicks Update Photo, PHP can echo either like "Your picture was updated and saved! You might need to refresh the page few times to see the new picture." or an error message noting user that the file has not been saved.
It's kind of up to you how you want to track error messages, one way would be to use a variable that starts as an empty string which you set when an error happens. You can check if the variable is empty to figure out if an error already happened.
Link to comment
Share on other sites

That is true, I should put more effort into filtering/cleaning user input as well as validate the data ^^ Thanks for sharing your script, it will take tiny while to figure it out but I will figure it out some time ^^, O, yes one more question. Whats better including files into one specific file? or placing the code in that file rather then including it?

Link to comment
Share on other sites

Whats better including files into one specific file? or placing the code in that file rather then including it?
It depends what the situation is, there's no one method that is always better for every situation.
Link to comment
Share on other sites

Hmm, Ok I updated my code you no longer see the crappy white border/pixelation around the images. However PNG images still have black bg even so I want them to be transparent. I updated the functions.php code, but it still seems not to do what it has to do.here is the code, can some one point where am I going wrong? imagesavealpha($im, true); is set to true, and imagealphablending($im, false); is set to false its set back to true a bit latter in the code.

<?phpfunction createThumbnail($new_file) {    	require 'config.php'; 	  	if(preg_match('/[.](jpg)$/', $new_file)) {  		$im = imagecreatefromjpeg($path_to_image_directory . $new_file); 			} else if (preg_match('/[.](gif)$/', $new_file)) {  		$im = imagecreatefromgif($path_to_image_directory . $new_file);		imagecolortransparent($im, black);			} else if (preg_match('/[.](png)$/', $new_file)) {  		$im = imagecreatefrompng($path_to_image_directory . $new_file);		imagealphablending($im, false);		imagesavealpha($im, true);			}    	$ox = imagesx($im);  	$oy = imagesy($im);    	$nx = $final_width_of_image;  	$ny = floor($oy * ($final_width_of_image / $ox));   	$nm = imagecreatetruecolor($nx, $ny);	imagealphablending($im, false);	  	imagecopyresampled($nm, $im, 0, 0, 0, 0,$nx,$ny,$ox,$oy);  	imagealphablending($im, true);		if(!file_exists($path_to_thumbs_directory)) {  	  if(!mkdir($path_to_thumbs_directory)) {  		   die("There was a problem. Please try again!");  	  }  	   }    	imagejpeg($nm, $path_to_thumbs_directory . "medium_". $new_file, 1000);		$t = time();			$tn = '<img src="' . $path_to_thumbs_directory . "medium_" . $new_file . '" alt="image" />';  	# $tn .= '<br />Congratulations. Your file has been successfully uploaded, and a thumbnail has been created.';  	echo $tn;  }  function createDisplaypic($new_file) {    	require 'config.php'; 	  	if(preg_match('/[.](jpg)$/', $new_file)) {  		$im = imagecreatefromjpeg($path_to_image_directory . $new_file); 			} else if (preg_match('/[.](gif)$/', $new_file)) {  		$im = imagecreatefromgif($path_to_image_directory . $new_file);			imagecolortransparent($im, black);			} else if (preg_match('/[.](png)$/', $new_file)) {				$im = imagecreatefrompng($path_to_image_directory . $new_file);		imagealphablending($im, false);		imagesavealpha($im, true);			}    	$ox = imagesx($im);  	$oy = imagesy($im);    	$nx = $final_width_of_dp;  	$ny = floor($oy * ($final_width_of_dp / $ox));    	$nm = imagecreatetruecolor($nx, $ny);	imagealphablending($im, false);		  	imagecopyresampled($nm, $im, 0,0,0,0,$nx,$ny,$ox,$oy); 			imagealphablending($im, true);		if(!file_exists($path_to_dp_directory)) {  	  if(!mkdir($path_to_dp_directory)) {  		   die("There was a problem. Please try again!");  	  }  	   }  	  	imagejpeg($nm, $path_to_dp_directory . "large_". $new_file, 1000);}  ?>

That reminds me, the code is using imagejpeg($nm, $path_to_thumbs_directory . "medium_". $new_file, 1000);, and the other part of code. Can this be the problem? as the script is forcing image to be made from JPEG

Link to comment
Share on other sites

Using transparency requires more than just toggling alpha blending on and off, there's a large if statement in the function I posted to do transparency for either a PNG or GIF. And yes, JPG images do not support transparency so if you're saving everything as a JPG then nothing will have a transparent background.

Link to comment
Share on other sites

Ye, I was wondering where was the problem, it seems my script is very outdated ^^. + I never included file format validation. I was also thinking of using switch() class to perform creation of the image. Since that way PHP can call file $ext and if file is .png go to case png and from there own perform required task ^^

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...