Hi everyone.
So I'm trying to make a thumbnails for the products from my shopping cart. A script wa suggested to me which is this:
http://shiftingpixel.com/2008/03/03/smart-image-resizer/
Which looks simple and nice.
The problem is this:
When I merge the script and my code together I get this (the file is called image.php):

<td cless="productWrap">
<td class="productItem" style="">
<a class="productImage" href="<?php echo $pd_image; ?>" rel="prettyPhoto" title="<?php echo $pd_name;?>" style="">
<img src="http://www.example.com/image.php?<?php echo $pd_image; ?>?width=180&height=180&image=<?php echo $pd_image; ?>" alt="<?php echo $pd_name; ?>">
</a>
</td>

Now the problem is that the photo doesn't show at all. When I copy the image URL I get this:

http://www.example.com/image.php?width=180&height=180&image=http://www.example.com/images/product/ea723c7a2658ac701a45a583986b5da4.jpg

And I think that's exactly what my link should be.
But when I run this on my browser I get this error:

Warning: file_exists() [function.file-exists]: open_basedir restriction in effect. File(/usr/local/apache/htdocs/images/product/ea723c7a2658ac701a45a583986b5da4.jpg) is not within the allowed path(s): (/home/:/usr/lib/php:/tmp) in /home/a3694407/public_html/image.php on line 96

Oh and the code of the script is this:

<?php
// Smart Image Resizer 1.4.1
// Resizes images, intelligently sharpens, crops based on width:height ratios, color fills
// transparent GIFs and PNGs, and caches variations for optimal performance

// Created by: Joe Lencioni (http://shiftingpixel.com)
// Date: August 6, 2008
// Based on: http://veryraw.com/history/2005/03/image-resizing-with-php/

/////////////////////
// LICENSE
/////////////////////

// I love to hear when my work is being used, so if you decide to use this, feel encouraged
// to send me an email. Smart Image Resizer is released under a Creative Commons
// Attribution-Share Alike 3.0 United States license
// (http://creativecommons.org/licenses/by-sa/3.0/us/). All I ask is that you include a link
// back to Shifting Pixel (either this page or shiftingpixel.com), but don’t worry about
// including a big link on each page if you don’t want to–one will do just nicely. Feel
// free to contact me to discuss any specifics (joe@shiftingpixel.com).

/////////////////////
// REQUIREMENTS
/////////////////////

// PHP and GD

/////////////////////
// PARAMETERS
/////////////////////

// Parameters need to be passed in through the URL's query string:
// image		absolute path of local image starting with "/" (e.g. /images/toast.jpg)
// width		maximum width of final image in pixels (e.g. 700)
// height		maximum height of final image in pixels (e.g. 700)
// color		(optional) background hex color for filling transparent PNGs (e.g. 900 or 16a942)
// cropratio	(optional) ratio of width to height to crop final image (e.g. 1:1 or 3:2)
// nocache		(optional) does not read image from the cache
// quality		(optional, 0-100, default: 90) quality of output image

/////////////////////
// EXAMPLES
/////////////////////

// Resizing a JPEG:
// <img src="/image.php/image-name.jpg?width=100&amp;height=100&amp;image=/path/to/image.jpg" alt="Don't forget your alt text" />

// Resizing and cropping a JPEG into a square:
// <img src="/image.php/image-name.jpg?width=100&amp;height=100&amp;cropratio=1:1&amp;image=/path/to/image.jpg" alt="Don't forget your alt text" />

// Matting a PNG with #990000:
// <img src="/image.php/image-name.png?color=900&amp;image=/path/to/image.png" alt="Don't forget your alt text" />

/////////////////////
// CODE STARTS HERE
/////////////////////

if (!isset($_GET['image']))
{
	header('HTTP/1.1 400 Bad Request');
	echo 'Error: no image was specified';
	exit();
}

define('MEMORY_TO_ALLOCATE',	'100M');
define('DEFAULT_QUALITY',		90);
define('CURRENT_DIR',			dirname(__FILE__));
define('CACHE_DIR_NAME',		'/imagecache/');
define('CACHE_DIR',				CURRENT_DIR . CACHE_DIR_NAME);
define('DOCUMENT_ROOT',			$_SERVER['DOCUMENT_ROOT']);

// Images must be local files, so for convenience we strip the domain if it's there
$image			= preg_replace('/^(s?f|ht)tps?:\/\/[^\/]+/i', '', (string) $_GET['image']);

// For security, directories cannot contain ':', images cannot contain '..' or '<', and
// images must start with '/'
if ($image{0} != '/' || strpos(dirname($image), ':') || preg_match('/(\.\.|<|>)/', $image))
{
	header('HTTP/1.1 400 Bad Request');
	echo 'Error: malformed image path. Image paths must begin with \'/\'';
	exit();
}

// If the image doesn't exist, or we haven't been told what it is, there's nothing
// that we can do
if (!$image)
{
	header('HTTP/1.1 400 Bad Request');
	echo 'Error: no image was specified';
	exit();
}

// Strip the possible trailing slash off the document root
$docRoot	= preg_replace('/\/$/', '', DOCUMENT_ROOT);

if (!file_exists($docRoot . $image))
{
	header('HTTP/1.1 404 Not Found');
	echo 'Error: image does not exist: ' . $docRoot . $image;
	exit();
}

// Get the size and MIME type of the requested image
$size	= GetImageSize($docRoot . $image);
$mime	= $size['mime'];

// Make sure that the requested file is actually an image
if (substr($mime, 0, 6) != 'image/')
{
	header('HTTP/1.1 400 Bad Request');
	echo 'Error: requested file is not an accepted type: ' . $docRoot . $image;
	exit();
}

$width			= $size[0];
$height			= $size[1];

$maxWidth		= (isset($_GET['width'])) ? (int) $_GET['width'] : 0;
$maxHeight		= (isset($_GET['height'])) ? (int) $_GET['height'] : 0;

if (isset($_GET['color']))
	$color		= preg_replace('/[^0-9a-fA-F]/', '', (string) $_GET['color']);
else
	$color		= FALSE;

// If either a max width or max height are not specified, we default to something
// large so the unspecified dimension isn't a constraint on our resized image.
// If neither are specified but the color is, we aren't going to be resizing at
// all, just coloring.
if (!$maxWidth && $maxHeight)
{
	$maxWidth	= 99999999999999;
}
elseif ($maxWidth && !$maxHeight)
{
	$maxHeight	= 99999999999999;
}
elseif ($color && !$maxWidth && !$maxHeight)
{
	$maxWidth	= $width;
	$maxHeight	= $height;
}

// If we don't have a max width or max height, OR the image is smaller than both
// we do not want to resize it, so we simply output the original image and exit
if ((!$maxWidth && !$maxHeight) || (!$color && $maxWidth >= $width && $maxHeight >= $height))
{
	$data	= file_get_contents($docRoot . '/' . $image);
	
	$lastModifiedString	= gmdate('D, d M Y H:i:s', filemtime($docRoot . '/' . $image)) . ' GMT';
	$etag				= md5($data);
	
	doConditionalGet($etag, $lastModifiedString);
	
	header("Content-type: $mime");
	header('Content-Length: ' . strlen($data));
	echo $data;
	exit();
}

// Ratio cropping
$offsetX	= 0;
$offsetY	= 0;

if (isset($_GET['cropratio']))
{
	$cropRatio		= explode(':', (string) $_GET['cropratio']);
	if (count($cropRatio) == 2)
	{
		$ratioComputed		= $width / $height;
		$cropRatioComputed	= (float) $cropRatio[0] / (float) $cropRatio[1];
		
		if ($ratioComputed < $cropRatioComputed)
		{ // Image is too tall so we will crop the top and bottom
			$origHeight	= $height;
			$height		= $width / $cropRatioComputed;
			$offsetY	= ($origHeight - $height) / 2;
		}
		else if ($ratioComputed > $cropRatioComputed)
		{ // Image is too wide so we will crop off the left and right sides
			$origWidth	= $width;
			$width		= $height * $cropRatioComputed;
			$offsetX	= ($origWidth - $width) / 2;
		}
	}
}

// Setting up the ratios needed for resizing. We will compare these below to determine how to
// resize the image (based on height or based on width)
$xRatio		= $maxWidth / $width;
$yRatio		= $maxHeight / $height;

if ($xRatio * $height < $maxHeight)
{ // Resize the image based on width
	$tnHeight	= ceil($xRatio * $height);
	$tnWidth	= $maxWidth;
}
else // Resize the image based on height
{
	$tnWidth	= ceil($yRatio * $width);
 	$tnHeight	= $maxHeight;
}

// Determine the quality of the output image
$quality	= (isset($_GET['quality'])) ? (int) $_GET['quality'] : DEFAULT_QUALITY;

// Before we actually do any crazy resizing of the image, we want to make sure that we
// haven't already done this one at these dimensions. To the cache!
// Note, cache must be world-readable

// We store our cached image filenames as a hash of the dimensions and the original filename
$resizedImageSource		= $tnWidth . 'x' . $tnHeight . 'x' . $quality;
if ($color)
	$resizedImageSource	.= 'x' . $color;
if (isset($_GET['cropratio']))
	$resizedImageSource	.= 'x' . (string) $_GET['cropratio'];
$resizedImageSource		.= '-' . $image;

$resizedImage	= md5($resizedImageSource);
	
$resized		= CACHE_DIR . $resizedImage;

// Check the modified times of the cached file and the original file.
// If the original file is older than the cached file, then we simply serve up the cached file
if (!isset($_GET['nocache']) && file_exists($resized))
{
	$imageModified	= filemtime($docRoot . $image);
	$thumbModified	= filemtime($resized);
	
	if($imageModified < $thumbModified) {
		$data	= file_get_contents($resized);
	
		$lastModifiedString	= gmdate('D, d M Y H:i:s', $thumbModified) . ' GMT';
		$etag				= md5($data);
		
		doConditionalGet($etag, $lastModifiedString);
		
		header("Content-type: $mime");
		header('Content-Length: ' . strlen($data));
		echo $data;
		exit();
	}
}

// We don't want to run out of memory
ini_set('memory_limit', MEMORY_TO_ALLOCATE);

// Set up a blank canvas for our resized image (destination)
$dst	= imagecreatetruecolor($tnWidth, $tnHeight);

// Set up the appropriate image handling functions based on the original image's mime type
switch ($size['mime'])
{
	case 'image/gif':
		// We will be converting GIFs to PNGs to avoid transparency issues when resizing GIFs
		// This is maybe not the ideal solution, but IE6 can suck it
		$creationFunction	= 'ImageCreateFromGif';
		$outputFunction		= 'ImagePng';
		$mime				= 'image/png'; // We need to convert GIFs to PNGs
		$doSharpen			= FALSE;
		$quality			= round(10 - ($quality / 10)); // We are converting the GIF to a PNG and PNG needs a compression level of 0 (no compression) through 9
	break;
	
	case 'image/x-png':
	case 'image/png':
		$creationFunction	= 'ImageCreateFromPng';
		$outputFunction		= 'ImagePng';
		$doSharpen			= FALSE;
		$quality			= round(10 - ($quality / 10)); // PNG needs a compression level of 0 (no compression) through 9
	break;
	
	default:
		$creationFunction	= 'ImageCreateFromJpeg';
		$outputFunction	 	= 'ImageJpeg';
		$doSharpen			= TRUE;
	break;
}

// Read in the original image
$src	= $creationFunction($docRoot . $image);

if (in_array($size['mime'], array('image/gif', 'image/png')))
{
	if (!$color)
	{
		// If this is a GIF or a PNG, we need to set up transparency
		imagealphablending($dst, false);
		imagesavealpha($dst, true);
	}
	else
	{
		// Fill the background with the specified color for matting purposes
		if ($color[0] == '#')
			$color = substr($color, 1);
		
		$background	= FALSE;
		
		if (strlen($color) == 6)
			$background	= imagecolorallocate($dst, hexdec($color[0].$color[1]), hexdec($color[2].$color[3]), hexdec($color[4].$color[5]));
		else if (strlen($color) == 3)
			$background	= imagecolorallocate($dst, hexdec($color[0].$color[0]), hexdec($color[1].$color[1]), hexdec($color[2].$color[2]));
		if ($background)
			imagefill($dst, 0, 0, $background);
	}
}

// Resample the original image into the resized canvas we set up earlier
ImageCopyResampled($dst, $src, 0, 0, $offsetX, $offsetY, $tnWidth, $tnHeight, $width, $height);

if ($doSharpen)
{
	// Sharpen the image based on two things:
	//	(1) the difference between the original size and the final size
	//	(2) the final size
	$sharpness	= findSharp($width, $tnWidth);
	
	$sharpenMatrix	= array(
		array(-1, -2, -1),
		array(-2, $sharpness + 12, -2),
		array(-1, -2, -1)
	);
	$divisor		= $sharpness;
	$offset			= 0;
	imageconvolution($dst, $sharpenMatrix, $divisor, $offset);
}

// Make sure the cache exists. If it doesn't, then create it
if (!file_exists(CACHE_DIR))
	mkdir(CACHE_DIR, 0755);

// Make sure we can read and write the cache directory
if (!is_readable(CACHE_DIR))
{
	header('HTTP/1.1 500 Internal Server Error');
	echo 'Error: the cache directory is not readable';
	exit();
}
else if (!is_writable(CACHE_DIR))
{
	header('HTTP/1.1 500 Internal Server Error');
	echo 'Error: the cache directory is not writable';
	exit();
}

// Write the resized image to the cache
$outputFunction($dst, $resized, $quality);

// Put the data of the resized image into a variable
ob_start();
$outputFunction($dst, null, $quality);
$data	= ob_get_contents();
ob_end_clean();

// Clean up the memory
ImageDestroy($src);
ImageDestroy($dst);

// See if the browser already has the image
$lastModifiedString	= gmdate('D, d M Y H:i:s', filemtime($resized)) . ' GMT';
$etag				= md5($data);

doConditionalGet($etag, $lastModifiedString);

// Send the image to the browser with some delicious headers
header("Content-type: $mime");
header('Content-Length: ' . strlen($data));
echo $data;

function findSharp($orig, $final) // function from Ryan Rud (http://adryrun.com)
{
	$final	= $final * (750.0 / $orig);
	$a		= 52;
	$b		= -0.27810650887573124;
	$c		= .00047337278106508946;
	
	$result = $a + $b * $final + $c * $final * $final;
	
	return max(round($result), 0);
} // findSharp()

function doConditionalGet($etag, $lastModified)
{
	header("Last-Modified: $lastModified");
	header("ETag: \"{$etag}\"");
		
	$if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH']) ?
		stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : 
		false;
	
	$if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ?
		stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']) :
		false;
	
	if (!$if_modified_since && !$if_none_match)
		return;
	
	if ($if_none_match && $if_none_match != $etag && $if_none_match != '"' . $etag . '"')
		return; // etag is there but doesn't match
	
	if ($if_modified_since && $if_modified_since != $lastModified)
		return; // if-modified-since is there but doesn't match
	
	// Nothing has changed since their last request - serve a 304 and exit
	header('HTTP/1.1 304 Not Modified');
	exit();
} // doConditionalGet()

// old pond
// a frog jumps
// the sound of water

// —Matsuo Basho
?>

Does someone know what is wrong with it?
Thank you in advance:-)

Recommended Answers

All 7 Replies

Member Avatar for diafol

sounds like you're trying to access a file to which you have no rights (open_basedir restriction).

Personally, I'd use a DB and a image_id to create the image. Perhaps that's just overkill?


images
id | filepathname | filetype | filesize | filedate | fileaspectratio |...

(fileaspectratio useful for quick calculations if only width or height given, although this can be done with php built-in image functions).

url:

http://www.example.com/image.php?id=3&w=200&h=150

The image.php file then just takes the querystring and queries the DB for image 3.

No offence, but that code looks a little overcomplicated for what you're using it for here. If just resizing, roll your own.

Yeah, I just need it to resize the pictures. I'm actually taking them from the database and the thing is, I needed something simple, just to to make all images the same size. But I guess this script is too complicated.
Is there some simple way just to resize the image without including other files (all to be done in the ProductDetail.php file)?

function resizeImage($sourceFile,$destFile,$width = '',$height ='')
{	
	$proportional = true;
	$output = 'file';
	copy($sourceFile,$destFile);
	
	$file = $destFile;
	if ( $height <= 0 && $width <= 0 ) return false;

	# Setting defaults and meta
	$info = getimagesize($file);
	$image = '';
	list($width_old, $height_old) = $info;	
	
	$final_width = 0;
	$final_height = 0;			
	
	$dims = getImageBound($width_old, $height_old,$width,$height);
	$final_height=$dims['height'];
	$final_width=$dims['width'];	
	if ( $width_old == $final_width && $height_old == $final_height ) return true;

	# Loading image to memory according to type
	switch ( $info[2] ) {
	  case IMAGETYPE_GIF: $image = imagecreatefromgif($file); break;
	  case IMAGETYPE_JPEG: $image = imagecreatefromjpeg($file); break;
	  case IMAGETYPE_PNG: $image = imagecreatefrompng($file); break;
	  default: return false;
	}		
	
	# This is the resizing/resampling/transparency-preserving magic
	$image_resized = imagecreatetruecolor( $final_width, $final_height );
	if ( ($info[2] == IMAGETYPE_GIF) || ($info[2] == IMAGETYPE_PNG) ) {
	  $transparency = imagecolortransparent($image);

	  if ($transparency >= 0) {
		$transparent_color = imagecolorsforindex($image, $trnprt_indx);
		$transparency = imagecolorallocate($image_resized, $trnprt_color['red'], $trnprt_color['green'], $trnprt_color['blue']);
		imagefill($image_resized, 0, 0, $transparency);
		imagecolortransparent($image_resized, $transparency);
	  }
	  elseif ($info[2] == IMAGETYPE_PNG) {
		imagealphablending($image_resized, false);
		$color = imagecolorallocatealpha($image_resized, 0, 0, 0, 127);
		imagefill($image_resized, 0, 0, $color);
		imagesavealpha($image_resized, true);
	  }
	}
	imagecopyresampled($image_resized, $image, 0, 0, 0, 0, $final_width, $final_height, $width_old, $height_old);		   

	# Preparing a method of providing result
	switch ( strtolower($output) ) {
	  case 'browser':
		$mime = image_type_to_mime_type($info[2]);
		header("Content-type: $mime");
		$output = NULL;
	  break;
	  case 'file':
		$output = $file;
	  break;
	  case 'return':
		return $image_resized;
	  break;
	  default:
	  break;
	}
	
	# Writing image according to type to the output destination
	switch ( $info[2] ) {
	  case IMAGETYPE_GIF: imagegif($image_resized, $output); break;
	  case IMAGETYPE_JPEG: imagejpeg($image_resized, $output); break;
	  case IMAGETYPE_PNG: imagepng($image_resized, $output); break;
	  default: return false;
	}
	//rename($file,$destFile);
	return true;
}
function getImageBound($oldW,$oldH,$newW='',$newH='')
{		
		$tempW = ( $oldW * $newH ) / ( $oldH ); 
		$tempH = ( $oldH * $newW ) / ( $oldW );
		
		if($newW =="" && $newH != "")
		{
			if($newH >$oldH)
			{
				$dims = getImageBound($oldW, $oldH,'',$oldH);
				$finalH = $dims['height'];
				$finalW = $dims['width'];		
			}
			else
			{
				$finalH = $newH;
				$finalW = $tempW;
			}
		}
		else if($newW !="" && $newH == "")
		{
			if($newW >$oldW)
			{
				$dims = getImageBound($oldW, $oldH,$oldW,'');
				$finalH = $dims['height'];
				$finalW = $dims['width'];		
			}
			else
			{
				$finalH = $tempH;
				$finalW = $newW;
			}
		}
		else if($newW !="" && $newH != "")
		{		
			if($tempW > $newW)
			{
				if($newW >$oldW)
				{
					$dims = getImageBound($oldW, $oldH,$oldW,'');
					$finalH = $dims['height'];
					$finalW = $dims['width'];		
				}
				else
				{
					$finalH = $tempH;
					$finalW = $newW;
				}
			}
			else
			{
				if($newH >$oldH)
				{
					$dims = getImageBound($oldW, $oldH,'',$oldH);
					$finalH = $dims['height'];
					$finalW = $dims['width'];		
				}
				else
				{
					$finalH = $newH;
					$finalW = $tempW;
				}
			}			
		}		
		$dims['height'] = $finalH;
		$dims['width'] = $finalW;
		return $dims;
	}

I was also facing problem for image resizing. Finally i have created this two functions.
Hope this will also help you.
Usage : resizeImage('upload/original/abc.jpg','upload/thumb/abc.jpg',400,500)
Try this and let me know your feedback.

I'm sorry, maybe this will sound dumb, but how can I hook this code to my code?
I'll save it under image.php and then I will hook it like this:

<td cless="productWrap">
<td class="productItem" style="">
<a class="productImage" href="<?php echo $pd_image; ?>" rel="prettyPhoto" title="<?php echo $pd_name;?>" style="">
<img src="http://www.example.com/image.php?<?php echo $pd_image; ?>" alt="<?php echo $pd_name; ?>">
</a>
</td>

Or should I just require_once (image.php) and something like that?
I take the images from the database, and that's why everything is a bit confusing for me.

Member Avatar for diafol

If you just want them all the same size, how about this:

<img src="..." width="..." height="..." />

You just use the width and height properties to resize. If you want them scaled, just use one property:

<img src="..." height="..." />

this will give you images of the same height, but may have different widths.


That's the easiest way in my opinion. No messing with graphics functions in php! I *assume* that this would be a lot quicker too.

Member Avatar for diafol
<a class="productImage" href="<?php echo $pd_image; ?>" rel="prettyPhoto" title="<?php echo $pd_name;?>" style="">
<img src="http://www.example.com/image.php?<?php echo $pd_image; ?>?width=180&height=180&image=<?php echo $pd_image; ?>" alt="<?php echo $pd_name; ?>">

goes to

<a class="productImage" href="<?php echo $pd_image; ?>" rel="prettyPhoto" title="<?php echo $pd_name;?>" style="">
<img src="<?php echo $pd_image; ?>" width="180" height="180" alt="<?php echo $pd_name; ?>">

@ardav I can't THANK YOU enough.
You have no idea how many days I were trying to make this work, and all I needed were a 2 simple width and height.
THANK YOU again. This is amazing!!!

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.