Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Resize image and save into mySQL

Status
Not open for further replies.

d0nny

IS-IT--Management
Dec 18, 2005
278
GB

Hi

I've been messing around with this all day and can't seem to get it working.

What I want is for a user to upload an image, check that the image is no greater than a certain width or height (say width <= 500), then save that filename in a database field, resize the image to a thumbnail of a certain size (say 100) and keep the aspect ratio and also store the filename of the thumbnail in a separate database field (I'm not storing the images in the database [blob] just the filename).

Can anyone offer suggestions?
 
If you can wait until Sunday I will find a script that I posted here the other day.
 
couldn't find a full function script in my archives (most probably on another computer) so i have penned a quick alternative.

this has not been tested so post back with syntax errors and functional problems.

Code:
<?php
/**
 * class to take an image in gif/png/jpeg formats and rescale it downwards to a particular dimension, finally saving it in a given path
 * 
 * if a corresponding filename already exists at the given path, a suffix will be appended
 * 
 * sample usage
 * 
$iR = new imageResizer('imagename.png', 100, '.');
if ($iR->isError()){
	$iR->outputErrors();
}
$result = $iR->convert();
if ($result == false){
	$iR->outputErrors();
} else {
	echo $result;
}
 * 
 */
class imageResizer{
	private $error = false;
	private $errorMessages = array();
	
	/**
	 * constructor 
	 * 
	 * @param object $file the full path of the image to be resampeld
	 * @param object $maxDimension the maximum permitted dimension
	 * @param object $outputDirectory  the output directory for the resultant file 
	 * @param object $outputFileName [optional]  if no value is provided a unique name will be created
	 * @return 
	 */
	public function __construct($file, $maxDimension,  $outputDirectory, $outputFileName = null){
		$this->setInputFile($file);
		$this->setMaxDimension($maxDimension);
		$this->setOutputDirectory($outputDirectory);
		$this->setImageData($file);
		$this->setOutputFileName($outputFileName);
	}
	
	/**
	 * method to determine the filename to use for the saved image.
	 * 
	 * if a file name is already taken a suffix (_XX) is appended before the extension
	 * @param object $file
	 * @return 
	 */
	
	private function setOutputFileName($file){
		if (empty($file)){
			$file = uniqid('', true);
		} else {
			$p = pathinfo($file);
			if (version_compare(PHP_VERSION, "5.2") === 1){
				$file = $p['filename'];
			} else {
				$file = substr($file, 0, (strlen($p['extension']) + 1) * -1);
			}
		}
		//now check whether the file name exists and appends an incrementing suffix if so
		$c = 0;
		if (file_exists($this->outputDirectory . $file . $this->extension)){
			do{
				$c++;
				$_file = $file . '_' . $c . $this->extension; 
			} while (file_exists($this->outputDirectory . $_file));
			$this->outputFile = $_file;
		} else {
			$this->outputFile = $file . $this->extension;
		}
	}
	
	/**
	 * method to set the maximum dimension of the new image
	 * @param object $dimension
	 * @return 
	 */
	private function setMaxDimension($dimension){
		if (is_numeric($dimension)){
			$this->dimension = $dimension;
		} else {
			$this->setError('Maximum Dimension is not numeric');
		}
	}
	
	/**
	 * method to set the output directory of the new image.
	 * 
	 * will test to ensure that the output directory exists and is writable.
	 * @param object $dir
	 * @return 
	 */
	private function setOutputDirectory($dir){
		if (is_dir($dir)){
			if (is_writable($dir)){
				$this->outputDirectory = realpath($dir);
				if (substr($this->outputDirectory, -1) != DIRECTORY_SEPARATOR){
					$this->outputDirectory .= DIRECTORY_SEPARATOR;
				}
			} else {
				$this->setError('Output Directory '. $dir . 'is not writable');
			}
		} else {
			$this->setError($dir .' is not a directory');
		}
	}
	
	/**
	 * method to set the input image for resampling.
	 * 
	 * will test to ensure that the file exists and is readable
	 * @param object $file
	 * @return 
	 */
	private function setInputFile($file){
		if (!is_file($file)){
			$this->setError($file .' does not exist');
		} elseif (!is_readable($file)){
				$this->setError($file .' is not readable');
		} else {
			$this->file = $file;
		}
	}
	
	/**
	 * method to set an error message
	 * @param object $message
	 * @return 
	 */
	private function setError($message){
		$this->error= true;
		$this->errorMessages[] = $message;
	}
	
	/**
	 * method to read in information about the image (height, width and image type)
	 * 
	 * @return 
	 */
	private function setImageData(){
		$data = getimagesize($this->file);
		$this->width = $data[0];
		$this->height = $data[1];
		$this->imageType = $data[2];
		$this->extension = image_type_to_extension($this->imageType);
	}
	
	/**
	 * method to determine whether a conversion is necessary (i.e. are both dimensions already below the required maximum)
	 * @return 
	 */
	private function needsConversion(){
		
		if ($this->height <= $this->dimension && $this->width <= $this->dimension){
			return false;
		} else {
			return true;
		}
	}
	
	/**
	 * method that performs the resampling
	 * @return false on error or the full canonical path of the resultant image
	 */
	public function convert(){
		if (!$this->needsConversion()){
			$output = $this->outputDirectory . $this->outputFile;
			$result = copy($this->file, $output);
			if (!$result){
				$this->setError('Cannot move uploaded file that does not need conversion');
				return false;
			} else {
				return $output;
			}
		}
		//calculate new sizes
		if ($this->height > $this->width){
			$this->newHeight = $this->dimension;
			$this->newWidth = $this->dimension * $this->width/$this->height;
		} else {
			$this->newWidth = $this->dimension;
			$this->newHeight = $this->dimension * $this->height/$this->width;
		}
		//create new canvas
		$nC = imagecreatetruecolor($this->newWidth, $this->newHeight);
		if (!$nC){
			$this->setError('Cannot create new image canvas');
		}
		
		//open up old image
		$oI = $this->getCurrentImage();
		if (!$oI){
			$this->setError('Image Type is unsupported');
		}
		
		//merge images
		imagecopyresampled ( $nC, $oI, 0,0,0,0 , $this->newWidth, $this->newHeight,  $this->width, $this->height );
		
		//now output the new image
		
		$output = $this->outputDirectory . $this->outputFile;
		if (call_user_func($this->outputFunction,$nC, $output, 100)){
			return $output;
		} else {
			$this->setError('Cannot output the image to file');
			return false;
		}
	}
	
	/**
	 * method to create a gd image resource and determine what type of output function to use
	 * 
	 * @return false on error or an imageresource if successful
	 */
	public function getCurrentImage(){
		switch ($this->imageType){
			case IMAGETYPE_GIF:
				$this->outputFunction = 'imagegif';
				return imagecreatefromgif($this->file);
			case IMAGETYPE_JPEG:
				$this->outputFunction = 'imagejpeg';
				return imagecreatefromjpeg($this->file);
			case IMAGETYPE_PNG:
				$this->outputFunction = 'imagepng';
				return imagecreatefrompng($this->file);
			default:
				
				return false;
		}
	}
	
	/**
	 * method to output errors to the browser.
	 * kills the script execution after
	 * @return 
	 */
	public function outputErrors(){
		echo implode ("\r\n<br/>", $this->errorMessages);
		exit;
	}
	
	/**
	 * method to determine the error state of the script
	 * @return bool true if errors exist
	 */
	public function isError(){
		if (empty($this->error) || $this->error === false){
			return false;
		} else {
			return true;
		}
	}
}
$iR = new imageResizer('imagename.png', 100, '.'); //save with random name in current working directory
if ($iR->isError()){
	$iR->outputErrors();
}
$result = $iR->convert();
if ($result == false){
	$iR->outputErrors();
} else {
	echo $result;
}

?>
 
Woah!
That, to me, looks far too complex for me to decipher!

Can you give me an example or explanation of how this works?
I mean, would I save this to an external file and 'include' it in my main page?
Then use the 'sample usage' you posted?
 
That would be fine. So long as php knows about the class it will work. Full comments are provided and the code is very straightforward: jus broken down into bite sized chunks
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top