<?php

// version 1.0
// last modified: 16th April, 2008
// modified by: Shashwat Parhi

// filename includes path
// $dest_details is an array with destination folder and destination size info
// check dimensions of source image and calculate W/H ratio and compute final sizes for dest image

function ResampleImage($filename, $dest_details, $crop=false, $sharpen=false)
{
$left = 0;
$top = 0;

	list($sourceW, $sourceH, $Image_type) = getimagesize($filename);

	if ($Image_type == IMAGETYPE_JPEG)
		$source_image = imagecreatefromjpeg($filename);
	else if ($Image_type == IMAGETYPE_PNG)
		$source_image = imagecreatefrompng($filename);
	else return false;

	for ($j = 0; $j < count($dest_details); $j++)
	{		
		list($destW, $destH, $dest_folder) = $dest_details[$j];

		if (strpos($filename, "/") !== false)
			 $filename_frompath = substr(strrchr($filename, "/"), 1);
		else
			 $filename_frompath = $filename;
		$newfile = $dest_folder . $filename_frompath;
	
		if (!$destW || !$destH || !file_exists($dest_folder))
			continue;
		
		if ($destW == $sourceW && $destH == $sourceH)			// if sizes match don't do any image processing
		{
			copy($filename, $newfile);
			continue;
		}
		
		if ($crop)												// we want to scale image and crop to dest dimensions
		{
			$scaledW = $sourceH / $destH * $destW;				// calculate scaled width of destination
			$scaledH = $sourceW / $destW * $destH;				// calculate scaled height of destination
			
			if ($scaledW < $sourceW)							// if scale up destination will fit source, widthwise
			{
				$left = floor(($sourceW - $scaledW) / 2);		// offset from center of source height from where to crop
				$sourceW = floor($scaledW);
				$top = 0;
			}
			else												// too wide, so consider a vertical fit
			{
				$left = 0;
				$top = floor(($sourceH - $scaledH) / 2);		// offset from center of source width from where to crop
				$sourceH = floor($scaledH);
			}
		}
		else													// we want to scale source to fit into dest box
		{
			//check if source image is smaller than target size			
			if (($destW > $sourceW) && ($destH > $sourceH))
			{
				$destW = $sourceW;
				$destH = $sourceH;
				$sharpen = false;
			}
			else
			{			
				$r = $sourceW / $sourceH;
				
				if ($destW / $destH > $r)
					$destW = floor($destH * $r);
				else $destH = floor($destW / $r);
			}
		}
		
	//	print "\$left = $left, \$top = $top, \$destW = $destW, \$destH = $destH, \$sourceW = $sourceW, \$sourceH = $sourceH";
	
		$dest_image = imagecreatetruecolor($destW, $destH);

	// Lessen the effect of a filter by increasing the value in the center cell;
	// compensate with the appropriate Divisor to maintain the brightness of the original image.
	
	//	$sharpenMatrix = array(array(-1,-1,-1),array(-1,16,-1),array(-1,-1,-1));
	//	$divisor = 8;
	//	$offset = 0;


	// Sharpen the image based on two things:
		//	(1) the difference between the original size and the final size
		//	(2) the final size
		$sharpness	= FindSharpness($sourceW, $destW);
		
		$sharpenMatrix	= array(
			array(-1, -2, -1),
			array(-2, $sharpness + 12, -2),
			array(-1, -2, -1)
		);
		$divisor		= $sharpness;
		$offset			= 0;
	
		//check if image is a jpeg or png
		if ($Image_type == IMAGETYPE_JPEG)
		{
			imagecopyresampled($dest_image, $source_image, 0, 0, $left, $top, $destW, $destH, $sourceW, $sourceH);
			if ($sharpen)
				imageconvolution($dest_image, $sharpenMatrix, $divisor, $offset);
			imagejpeg($dest_image, $newfile);
		}
		else if ($Image_type == IMAGETYPE_PNG)
		{
			imagealphablending($dest_image, false);
			imagecopyresampled($dest_image, $source_image, 0, 0, $left, $top, $destW, $destH, $sourceW, $sourceH);
			if ($sharpen)
				imageconvolution($dest_image, $sharpenMatrix, $divisor, $offset);
			imagesavealpha($dest_image, true);
			imagepng($dest_image, $newfile);
		}
		imagedestroy($dest_image);
	}

	imagedestroy($source_image);

	return true;
}

// function from Ryan Rud (http://adryrun.com)
function FindSharpness($orig, $final)
{
	$final	= $final * (750.0 / $orig);
	$a		= 52;
	$b		= -0.27810650887573124;
	$c		= .00047337278106508946;
	
	$result = $a + $b * $final + $c * $final * $final;
	
	return max(round($result), 0);
}
?>
