Skip to content

Instantly share code, notes, and snippets.

@shayanderson
Created January 29, 2014 15:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save shayanderson/8690557 to your computer and use it in GitHub Desktop.
Save shayanderson/8690557 to your computer and use it in GitHub Desktop.
Image Resizer class ImageResizer.php
<?php
/**
* Image Resizer / Thumbnail Creator
*
* NOTE: Requires the GD lib:
* http://php.net/manual/en/book.image.php
*
* @package ImageResizer
* @name ImageResizer
* @author Shay Anderson 3.12
*/
class ImageResizer {
/**
* Counters
*
* @var int
*/
private $_counter_copied = 0;
private $_counter_dirs = 0;
private $_counter_resized = 0;
private $_counter_total = 0;
/**
* Image types
*
* @var array
*/
private static $_types = array(
1 => 'gif',
2 => 'jpeg',
3 => 'png',
6 => 'bmp'
);
/**
* Copy unsized images flag (will copy all images to target directory even if not resized)
*
* @var bool
*/
public $copy_unsized_images = false;
/**
* Prepend output image filename with postfix name
*
* @var string
*/
public $filename_postfix;
/**
* Append output image filename with prefix name
*
* @var string
*/
public $filename_prefix;
/**
* Max image dimension, if width/height over dimension image will be resized
*
* @var int
*/
public $max_dimension = 200;
/**
* Max image height, if image height is over max height image will be resized
* This overrides $max_dimension, but is overridden by $max_width
*
* @var int
*/
public $max_height = 0;
/**
* Max image width, if image width is over max width image will be resized
* This overrides $max_dimension and overrides $max_height
*
* @var int
*/
public $max_width = 0;
/**
* Overwrite existing output images flag
*
* @var bool
*/
public $overwrite = false;
/**
* Suppress overwrite error when overwrite is off flag
*
* @var bool
*/
public $overwrite_suppress_errors = false;
/**
* Recursive resize images
*
* @var bool
*/
public $recursive = true;
/**
* Verbose messages flag
*
* @var bool
*/
public $verbose = true;
/**
* Verbose messages newline character(s)
*
* @var string
*/
public $verbose_newline = '<br />';
/**
* Init
*/
public function __construct() {
// check for GD library
if(!function_exists('getimagesize')) {
trigger_error(__CLASS__ . ' requires the GD library', E_USER_ERROR);
}
}
/**
* Format output filename - adds prefix/postfix
*
* @param string $image_filename
* @return string
*/
private function _formatOutputFilename(&$image_filename) {
$ext = substr($image_filename, strrpos($image_filename, '.'), strlen($image_filename));
$filename = str_replace($ext, null, $image_filename);
return $this->filename_prefix . $filename . $this->filename_postfix . $ext;
}
/**
* Format path - add tail dir separator if needed
*
* @param string $path
* @return string
*/
private function _formatPath(&$path = null) {
if($path !== null && strlen($path) > 0 && substr($path, -1) != DIRECTORY_SEPARATOR) {
$path .= DIRECTORY_SEPARATOR;
}
return $path;
}
/**
* Process single image
*
* @param string $image_path
* @param string $image_output_path
*/
public function run($image_path, $image_output_path) {
$image_filename = null;
if(preg_match('/.*\.[\w]{1,4}$/', $image_path)) {
if(strpos($image_path, DIRECTORY_SEPARATOR) !== false) {
$image_filename = trim(substr($image_path, strrpos($image_path, DIRECTORY_SEPARATOR) + 1, strlen($image_path)));
} else {
$image_filename = $image_path;
}
} else {
trigger_error('Invalid image name "' . $image_path . '"', E_USER_ERROR);
}
// format image output path
$image_output_dir = null;
if($image_output_path !== null) {
// check for filename
if(preg_match('/.*\.[\w]{1,4}$/', $image_output_path)) {
// dir and filename
if(strpos($image_output_path, DIRECTORY_SEPARATOR) !== false) {
$image_output_dir = substr($image_output_path, 0, strrpos($image_output_path, DIRECTORY_SEPARATOR) + 1);
$image_output_path = substr($image_output_path, 0, strrpos($image_output_path, DIRECTORY_SEPARATOR) + 1)
. $this->_formatOutputFilename( substr($image_output_path, strrpos($image_output_path, DIRECTORY_SEPARATOR) + 1,
strlen($image_output_path)) );
// filename only
} else {
$image_output_path = $this->_formatOutputFilename($image_output_path);
}
// directory only
} else {
$image_output_dir = $this->_formatPath($image_output_path);
$image_output_path = $this->_formatPath($image_output_path) . $this->_formatOutputFilename($image_filename);
}
}
// check for valid image path
if(!is_readable($image_path) || !is_file($image_path)) {
trigger_error('Failed to read image path "' . $image_path . '"', E_USER_ERROR);
}
// check for valid output path
if(!is_writable($image_output_dir)) {
trigger_error('Failed to write to image output directory "' . $image_output_dir . '"', E_USER_ERROR);
}
// set image data
list($img_w, $img_h, $img_type) = getimagesize($image_path);
// check for valid image
if($img_type && isset(self::$_types[$img_type])) {
$this->_counter_total++;
// override max dimensions
if($this->max_width > 0) {
$this->max_dimension = $this->max_width;
}
if($this->max_height > 0) {
$this->max_dimension = $this->max_height;
}
// set new dimensions
$img_new_w = $img_new_h = 0;
if($this->max_width > 0 && $img_w > $this->max_width) {
$img_new_w = $this->max_width;
$img_new_h = round($img_h * ($img_new_w / $img_w));
} else if($this->max_height > 0 && $img_h > $this->max_height) {
$img_new_h = $this->max_height;
$img_new_w = round($img_w * ($img_new_h / $img_h));
} else if($img_w > $this->max_dimension || $img_h > $this->max_dimension) {
$img_new_w = $this->max_dimension;
$img_new_h = $this->max_dimension;
if($img_w > $img_h) {
$img_new_h = round($img_h * ($img_new_w / $img_w));
} else {
$img_new_w = round($img_w * ($img_new_h / $img_h));
}
}
// check if need resize
if($img_new_w > 0 && $img_new_h > 0) {
// resize image
if($this->verbose) {
echo $this->_counter_total . ': Processing image "' . $image_path . '"' . $this->verbose_newline;
}
$img_new = imagecreate($img_new_w, $img_new_h);
$f = 'imagecreatefrom' . self::$_types[$img_type];
$img = $f($image_path);
imagecopyresampled($img_new, $img, 0, 0, 0, 0, $img_new_w, $img_new_h, $img_w, $img_h);
// save image
if(!$this->overwrite && file_exists($image_output_path)) {
if(!$this->overwrite_suppress_errors) {
trigger_error('Failed to write file "' . $image_output_path . '", overwrite turned off', E_USER_ERROR);
}
} else {
$f = 'image' . self::$_types[$img_type];
$resized = false;
// fix png resize bug quality >= 9
if($img_type == 3) {
$resized = $f($img_new, $image_output_path, 8);
} else {
$resized = $f($img_new, $image_output_path);
}
if($resized === true) {
$this->_counter_resized++;
if($this->verbose) {
echo $this->_counter_total . ': Resized: "' . $image_path . '" => "' . $image_output_path . '"' . $this->verbose_newline;
}
} else {
trigger_error('Failed to write file "' . $image_output_path . '"', E_USER_ERROR);
}
}
imagedestroy($img_new);
imagedestroy($img);
// no resize, copy image
} else if($this->copy_unsized_images) {
if(copy($image_path, $image_output_path)) {
$this->_counter_copied++;
if($this->verbose) {
echo $this->_counter_total . ': Copied: "' . $image_path . '" => "' . $image_output_path . '"' . $this->verbose_newline;
}
} else {
trigger_error('Failed to copy unsized image "' . $image_output_path . '"', E_USER_ERROR);
}
}
}
}
/**
* Process images in directory to output directory
*
* @param string $source_path
* @param string $target_path
* @param bool $basedir
*/
public function runBatch($source_path, $target_path, $basedir = true) {
$source_path = $this->_formatPath($source_path);
$target_path = $this->_formatPath($target_path);
if(!is_dir($source_path)) {
trigger_error('Failed to read source path "' . $source_path . '"', E_USER_ERROR);
}
if(!is_dir($target_path) || !is_writable($target_path)) {
trigger_error('Failed to read/write target path "' . $target_path . '"', E_USER_ERROR);
}
if($d = opendir($source_path)) {
while(false !== ($f = readdir($d))) {
if($f != '.' && $f != '..') {
// process directory
if(is_dir($source_path . $f)) {
$dir = $source_path . $f;
$dir_out = $target_path . $f;
// create new sub dir
if($this->recursive) {
if($this->verbose) {
echo 'Processing directory "' . $dir . '"' . $this->verbose_newline;
}
if(!is_dir($dir_out)) {
if(mkdir($dir_out)) {
$this->_counter_dirs++;
if($this->verbose) {
echo 'Created sub directory: "' . $dir_out . '"' . $this->verbose_newline;
}
} else {
trigger_error('Failed to create sub directory "' . $dir_out . '"', E_USER_ERROR);
}
}
// process sub directory
$this->runBatch($dir, $dir_out, false);
}
// process image
} else {
$this->run($source_path . $f, $target_path . $f);
}
}
}
closedir($d);
if($this->verbose && $basedir) {
echo $this->verbose_newline . $this->_counter_resized . ' of ' . $this->_counter_total . ' images resized.'
. $this->verbose_newline . $this->_counter_copied . ' of ' . $this->_counter_total . ' images copied.'
. $this->verbose_newline . $this->_counter_dirs . ' directories created.' . $this->verbose_newline;
}
} else {
trigger_error('Failed to open directory "' . $source_path . '"', E_USER_ERROR);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment