Return to Snippet

Revision: 19349
at October 22, 2009 01:34 by Kit


Updated Code
<?php

	set_error_handler('showBrokenImage');

	$imagesFolder = 'images/'; // Change this if required to point to your source folder
	$brokenImage = $imagesFolder.'brokenimage.png';
	$thumbnailHeight = $thumbnailWidth = 80; // Set to the max size of your thumbnail
	$previewHeight = $previewWidth = 250; // Set to the max size of your preview images
	date_default_timezone_set('Australia/NSW'); // Remove or update this line depending on your PHP.ini settings

	try {
		if(empty($_SERVER['PATH_INFO']) || strpos($_SERVER['PATH_INFO'], ':') !== false || strpos($_SERVER['PATH_INFO'], '..') !== false) {
			throw new exception('Invalid path');
		}
	
		$pathComponents = explode('/', strtolower(trim((isset($_SERVER['PATH_INFO']) && strlen(trim($_SERVER['PATH_INFO'], '/')) ? $_SERVER['PATH_INFO'] : ''), '/')));
	
		if($pathComponents[0] === 'thumb') {
			$outputWidth = $thumbnailWidth;
			$outputHeight = $thumbnailHeight;
		} else {
			$outputWidth = $previewWidth;
			$outputHeight = $previewHeight;
		}
	
		function mkdir_recursive($pathname, $mode = 0777) {
			is_dir(dirname($pathname)) || mkdir_recursive(dirname($pathname), $mode);
			return is_dir($pathname) || @mkdir($pathname, $mode);
		}
	
		$file = $imagesFolder.trim(substr($_SERVER['PATH_INFO'], strlen('/'.$pathComponents[0])), '/');
		$fileExtension = strtolower(substr($file, strrpos($file, '.') + 1));
		
		if(!is_file($file)) {
			throw new exception('Invalid path');
		}
	
		if(in_array($pathComponents[0], array('thumb', 'preview'))) {
			// Generate a smaller image if we haven't already got one
			$thumbFile = str_replace($imagesFolder, $imagesFolder.($pathComponents[0] === 'thumb' ? 'thumbnails' : 'previews').'/', $file);
			if(!file_exists($thumbFile) && file_exists($file)) {
				// Generate a thumbnail
				switch($fileExtension) {
					case 'jpg':
					case 'jpeg':
						$sourceImage = imagecreatefromjpeg($file);
						break;
					
					case 'png':
						$sourceImage = imagecreatefrompng($file);
						break;
				}
				
				$sourceX = imagesx($sourceImage);
				$sourceY = imagesy($sourceImage);
				if ($sourceX > $sourceY) {
					$destinationWidth = $outputWidth;
					$destinationHeight = $sourceY * ($outputHeight/$sourceX);
				} else if ($sourceX < $sourceY) {
					$destinationWidth = $sourceX * ($outputWidth/$sourceY);
					$destinationHeight = $outputHeight;
				} else if ($sourceX == $sourceY) {
					$destinationWidth = $outputWidth;
					$destinationHeight = $outputHeight;
				}
	
				$outputImage = imagecreatetruecolor($destinationWidth, $destinationHeight);
				imagecopyresampled($outputImage, $sourceImage, 0, 0, 0, 0, $destinationWidth, $destinationHeight, $sourceX, $sourceY);
				
				// Make sure the destination folder path exists
				mkdir_recursive(dirname($thumbFile));
				
				switch($fileExtension) {
					case 'jpg':
					case 'jpeg':
						imagejpeg($outputImage, $thumbFile);
						break;
					
					case 'png':
						imagepng($outputImage, $thumbFile);
						break;
				}
			}
			
			$file = $thumbFile;
		}
	
		if(!file_exists($file)) {
			outputImage($brokenImage);
		}

		outputImage($file);
	} catch(exception $ex) {
		outputImage($brokenImage);
	}

	function outputImage($file) {
		error_reporting(0);
		$fileExtension = strtolower(substr($file, strrpos($file, '.') + 1));

		header('Last-Modified: '.@date('r', filemtime($file)));
		header('Accept-Ranges: bytes');		
		switch($fileExtension) {
			case 'jpg':
			case 'jpeg':
				header('Content-Type: image/jpeg');
				break;
			
			case 'png':
				header('Content-Type: image/png');
				break;
		}
		header('Content-Length: '.filesize($file));
		@ob_clean();
		flush();
		readfile($file);
		exit;
	}


	function showBrokenImage($errno, $errstr) {
		global $brokenImage;
	
		if(!in_array($errno, array(0, E_STRICT, E_NOTICE))) {
			outputImage($brokenImage);
		}

		return true; // Don't execute PHP internal error handler
	}

?>

Revision: 19348
at October 22, 2009 01:22 by Kit


Initial Code
<?php

	set_error_handler('showBrokenImage');

	$imagesFolder = 'images/'; // Change this if required to point to your source folder
	$brokenImage = $imagesFolder.'brokenimage.png';
	$thumbnailHeight = $thumbnailWidth = 80; // Set to the max size of your thumbnail
	$previewHeight = $previewWidth = 250; // Set to the max size of your preview images
	date_default_timezone_set('Australia/NSW'); // Remove or update this line depending on your PHP.ini settings

	try {
		if(empty($_SERVER['PATH_INFO']) || strpos($_SERVER['PATH_INFO'], ':') !== false || strpos($_SERVER['PATH_INFO'], '..') !== false) {
			throw new exception('Invalid path');
		}
	
		$pathComponents = explode('/', strtolower(trim((isset($_SERVER['PATH_INFO']) && strlen(trim($_SERVER['PATH_INFO'], '/')) ? $_SERVER['PATH_INFO'] : ''), '/')));
	
		if($pathComponents[0] === 'thumb') {
			$outputWidth = $thumbnailWidth;
			$outputHeight = $thumbnailHeight;
		} else {
			$outputWidth = $previewWidth;
			$outputHeight = $previewHeight;
		}
	
		function mkdir_recursive($pathname, $mode = 0777) {
			is_dir(dirname($pathname)) || mkdir_recursive(dirname($pathname), $mode);
			return is_dir($pathname) || @mkdir($pathname, $mode);
		}
	
		$file = $imagesFolder.trim(substr($_SERVER['PATH_INFO'], strlen('/'.$pathComponents[0])), '/');
		$fileExtension = strtolower(substr($file, strrpos($file, '.') + 1));
		
		if(!is_file($file)) {
			throw new exception('Invalid path');
		}
	
		if(in_array($pathComponents[0], array('thumb', 'preview'))) {
			// Generate a smaller image if we haven't already got one
			$thumbFile = str_replace($imagesFolder, $imagesFolder.($pathComponents[0] === 'thumb' ? 'thumbnails' : 'previews').'/', $file);
			if(!file_exists($thumbFile) && file_exists($file)) {
				// Generate a thumbnail
				switch($fileExtension) {
					case 'jpg':
					case 'jpeg':
						$sourceImage = imagecreatefromjpeg($file);
						break;
					
					case 'png':
						$sourceImage = imagecreatefrompng($file);
						break;
				}
				
				$sourceX = imagesx($sourceImage);
				$sourceY = imagesy($sourceImage);
				if ($sourceX > $sourceY) {
					$destinationWidth = $outputWidth;
					$destinationHeight = $sourceY * ($outputHeight/$sourceX);
				} else if ($sourceX < $sourceY) {
					$destinationWidth = $sourceX * ($outputWidth/$sourceY);
					$destinationHeight = $outputHeight;
				} else if ($sourceX == $sourceY) {
					$destinationWidth = $outputWidth;
					$destinationHeight = $outputHeight;
				}
	
				$outputImage = imagecreatetruecolor($destinationWidth, $destinationHeight);
				imagecopyresampled($outputImage, $sourceImage, 0, 0, 0, 0, $destinationWidth, $destinationHeight, $sourceX, $sourceY);
				
				// Make sure the destination folder path exists
				mkdir_recursive(dirname($thumbFile));
				
				switch($fileExtension) {
					case 'jpg':
					case 'jpeg':
						imagejpeg($outputImage, $thumbFile);
						break;
					
					case 'png':
						imagepng($outputImage, $thumbFile);
						break;
				}
			}
			
			$file = $thumbFile;
		}
	
		if(!file_exists($file)) {
			outputImage($brokenImage);
		}

		outputImage($file);
	} catch(exception $ex) {
		outputImage($brokenImage);
	}

	function outputImage($file) {
		error_reporting(0);
		$fileExtension = strtolower(substr($file, strrpos($file, '.') + 1));

		header('Last-Modified: '.@date('r', filemtime($file)));
		header('Accept-Ranges: bytes');		
		switch($fileExtension) {
			case 'jpg':
			case 'jpeg':
				header('Content-Type: image/jpeg');
				break;
			
			case 'png':
				header('Content-Type: image/png');
				break;
		}
		header('Content-Length: '.filesize($file));
		@ob_clean();
		flush();
		readfile($file);
		exit;
	}


	function showBrokenImage($errno, $errstr) {
		global $brokenImage;
	
		if(!in_array($errno, array(0, E_STRICT, E_NOTICE))) {
			//echo 'Issue!';
			outputImage($brokenImage);
		}
		//echo 'No real issue';

		return true; // Don't execute PHP internal error handler
	}

?>

Initial URL

                                

Initial Description
Not particularly novel, but quite clean. Allows you to put images in any location on the server and saves having to generate thumbnails at upload time.

The URL to this file should be:

`<filename.php>/<request>/<path>`

Valid request types:

* `view` — View the image full-size (don't scale)
* `preview` — View the image at a medium scale
* `thumb` — Show a thumbnail of the image

Images can be JPEGs or PNGs. Broken URLs redirect to a designated 404 image.

Thumbnails and previews will be stored using an identical folder hierarchy inside the `thumbnails` and `previews` folders inside the images folder.

Initial Title
Auto-generate thumbnail in equivalent location (unless one has been manually created)

Initial Tags
image

Initial Language
PHP