Source for file netpbmresize.class.php
Documentation is available at netpbmresize.class.php
* NetpbmResize is a php class that works as a wrapper for the netpbm binaries
* which are easily obtainable thanks to the Gallery project
* (http://tinyurl.com/25daoc). It is *only* focused on resizing images
* (by Width, Height, Percentage or Bounding Box) and create square thumbnails.
* It supports JPG, GIF and PNG.
* Its intended audience are php developers who are using images in their
* applications and need a resizing solution. Most common use would be an
* application which needs gallery functionality.
* @author Favio Manriquez <favio@favrik.com>
* Stores the filename of the resized image
* @var string resized image filename
* Working Directory. Most commonly: where you are storing or uploading
* @var string path of working directory
* Stores the command line parameteres of the different netpbm programs.
* An instance of the class ImageInfo that contains necessary information
* from the current initialized image. You can initialize an image by
* calling the method setImageInfo.
* @var object instance of ImageInfo class
* These strings appear in the filenames of the netpbm programs. This fact
* is used for calling a program dynamically since the only part of the
* name that changes is the format to be resized.
* @var array part of the names of the netpbm programs
var $Programs = array(1 => 'gif', 'jpeg', 'png');
* NetpbmResize doesn't delete the source image so you have to either
* define an output name (setOutputImage) or the resulting resized image
* name will contain this suffix. You can also change the suffix.
* @var string the default suffix of the resized image
* @param string $NetpbmPath path to netpbm binaries WITHOUT trailing slash
* @param string $Path path to working dir which may include the output filename
$this->setPathSeparator();
$this->setNetpbmPath($NetpbmPath);
$this->initialize($Path);
$this->DefaultSuffix = '.rs';
* Should use "const" when leaving PHP4 for good.
* @param string $Netpbm path to netpbm binaries
function setNetpbmPath($Netpbm) {
define('NETPBM_PATH', $Netpbm . DIR_SLASH);
* Tries to detect which trailing slash to use: unix like or windows like.
function setPathSeparator() {
$slash = (eregi("win",$_ENV['OS'])) ? '\\' : '/';
* Set working directory and image info if applicable.
* @param string $path working directory or absolute path of an image
function initialize($Path) {
* Initializes the ImageInfo object useful for retrieving Image info.
* @param string $Image full path to an image file
if (!$this->ImageInfo->validImage()) {
$this->raiseError('Image format not supported! Only JPG, GIF or PNG are supported.');
return $this->ImageInfo->width();
return $this->ImageInfo->height();
* Sets the default suffix of the the resized image.
* @param string $suffix suffix to be used for the resized image
$this->DefaultSuffix = $suffix;
* Sets the working directory.
* @param string $dir working directory
$this->WorkingDir = $dir;
* Gets the working directory.
* @return string working directory
return $this->WorkingDir;
* Sets the filename of the resized image.
* @param string $filename output image filename
$this->OutputImage = $filename;
* Gets the filename of the resized image.
* @return string output image filename
return $this->OutputImage;
* Checks if image is empty, if not sets the image info object
* @param string $image image name without path
* Returns the nice name (without spaces, special chars, etc.)
* of the last image processed.
* @return string image name
return $this->ImageInfo->name();
* Returns a command name with absolute path prepended.
* @param string $cmd program name
* @return string command with path and trailing space
return NETPBM_PATH . $cmd . ' ';
* Uses pnmcut to produce square thumbnails (pnmcut left top width height).
* First slices the square centered region of the input image and then
* resizes that to the dimension specified.
* @param int $size dimension
* @param string $suffix_op optional suffix for resulting image
$suffix = empty($suffix_op) ? $size : $suffix_op;
$this->Params = '-width ' . $size . ' ';
$cmd = $this->getPreCommand() . $this->getThumbnailCommand() . $this->getPostCommand();
$this->setOutputImage(''); // reset Output image for next images to be processed
* Calculates the dimensions required to slice a square from the original
* image. This is used as the new source for the resizing program.
* @return string command line to be executed
function getThumbnailCommand() {
$min = ($this->ImageInfo->width() > $this->ImageInfo->height()) ? 'height' : 'width';
$max = ($this->ImageInfo->width() > $this->ImageInfo->height()) ? 'width' : 'height';
$max_value = intval ( ($this->ImageInfo->{$max}() - $this->ImageInfo->{$min}()) / 2 );
$width = $height = $this->ImageInfo->height();
$width = $height = $this->ImageInfo->width();
return $this->command('pnmcut') . $left . ' '. $top . ' '. $width . ' ' . $height . ' | ';
* Cuts an image section to be taken as the base for a specific width and
* @param int $x target width of image
* @param int $y target height of image
* @return string command line to be executed
function getFixedCut($x, $y) {
$max = max($width_factor, $height_factor);
$difference = abs($width_factor - $height_factor);
if ($max == $width_factor) {
$width = $width_factor * $x - ($difference * $x);
$height = $height_factor * $y;
$width = $width_factor * $x;
$height = $height_factor * $y - ($difference * $y);
return $this->command('pnmcut') . $left . ' '. $top . ' '. $width . ' ' . $height . ' | ';
* Generic resize method, it defaults to resize by Bounding Box. The first
* parameter can also be an array containing different dimensions and
* suffixes so you can have different resized versions of the original
* @param mixed $pixels pixels to be resized by
* @param string $image input image filename
* @see resizeByBoundingBox()
function resize($pixels, $image = '') {
foreach ($pixels as $size => $suffix) {
* Resizes an image taking width as the base dimension.
* @param integer $pixels pixels to be resized by
* @param string $image input image filename
$this->Params = '-width ' . $pixels . ' ';
* Resizes an image taking height as the base dimension.
* @param integer $pixels pixels to be resized by
* @param string $image input image filename
$this->Params = '-height ' . $pixels . ' ';
* Resizes an image by a percentage.
* @param mixed $percentage float or int taken as a percentage
* @param string $image input image filename
$this->Params = $percentage . ' ';
* This does a bounding box resize. It will try to fit the image into
* a box with the columns and rows specified.
* @param integer $cols number of columns of the bounding box
* @param integer $rows number of rows of the bounding box
* @param string $image input image filename without path info
$this->Params = '-xysize ' . $cols . ' ' . $rows . ' ';
* This does a specific resize. It resizes the image to the specified
* dimensions without altering the aspect ratio, but of course the
* algorithm used centers the new frame and some portions of the image are
* lost. Also, the original image should be larger than the target image.
* @param integer $width target width of image
* @param integer $height target height of image
* @param string $suffix image suffix to be used
* @param string $image input image filename without path info
$suffix = empty($suffix) ? $width : $suffix;
$this->Params = '-width ' . $width . ' -height ' . $height . ' ';
$cmd = $this->getPreCommand() . $this->getFixedCut($width, $height) . $this->getPostCommand();
$this->setOutputImage(''); // reset Output image for next images to be processed
* If an image path was passed it will initialize it and resize using that
* instead. Compiles the command to be called for resizing.
* @param string $image image filename to be initialized
function process($image = '') {
$this->raiseError('You have not setup an Image!');
$cmd = $this->getPreCommand() . $this->getPostCommand();
* Executes a command line to resize an image.
* @param string $cmd command line to be executed
exec($cmd, $output, $return_var);
$this->raiseError('Error at netpbm execution, full command line: '. $cmd);
* Compiles the first part of the command line to be executed.
* @return string first part of the command line
function getPreCommand() {
return $this->command($this->Programs[$this->ImageInfo->type()] . 'topnm')
* Compiles the last part of the command line to be executed. This is where
* format based logic occurs and the reason why $this->Programs exist.
* @return string last part the command line
function getPostCommand() {
$Type = $this->Programs[$this->ImageInfo->type()];
$Command = $this->command('pnmscale') . $this->Params . ' | ';
$Command .= $this->command('ppmquant') . '256 | '
. $this->command('ppmto' . $Type) . '> ';
$options = ($Type == 'jpeg') ? '--quality=95 ' : '';
$Command .= $this->command('pnmto' . $Type) . $options . '> ';
* Calculates the resized image filaname since it can come from $OutputImage
* or just be the original filename with a suffix appended.
* @return string final full path of the resized image
$OutputFile = empty($file)
? $this->ImageInfo->customName($this->DefaultSuffix) : $file;
$OutputFile .= '.' . $this->ImageInfo->extension();
* Triggers an USER error. This should/could be changed touse a custom
* @param string $message message to be displayed in case of user error
function raiseError($message) {
* Stores all the required/useful information of a given image in an array
* and provides accessor methods to that data.
* @author Favio Manriquez <favio@favrik.com>
* Used to store and retrieve all the image info.
* @var array stores all the image info
var $ImageInfo = array();
* Stores the supported image formats.
* @var array image formats
var $SupportedTypes = array(1 => 'gif', 'jpg', 'png');
* Constructor. Uses getimagesize() output as initial data.
* @param string $image full path of an image
$this->ImageInfo['width'] = $size[0];
$this->ImageInfo['height'] = $size[1];
$this->ImageInfo['type'] = $size[2];
$this->ImageInfo['mime'] = $size['mime'];
$this->ImageInfo['route'] = $Image;
$this->ImageInfo['original_name'] = basename($Image);
* Checks if image is of a supported format.
$this->ImageInfo['ext'] = $this->SupportedTypes[$this->ImageInfo['type']];
* Regular expressions taken from gallery.menalto.com. It produces nice
$name = urldecode($this->ImageInfo['original_name']); // remove %20 and the like from name
$tag = $this->ImageInfo['ext'];
$tempFilename = eregi_replace(".$tag$", "", $name);// parse out original filename without extension
$tempFilename = ereg_replace("[^[:alnum:]]", "_", $tempFilename);// replace multiple non-word characters with a single "_"
$tempFilename = ereg_replace("_+", "_", $tempFilename);// Get rid of extra underscores
if ($name != $tempFilename) {
$this->renameImage($tempFilename . '.' . $tag);
$this->ImageInfo['nice_name'] = $tempFilename;
$this->ImageInfo['temp_name'] = $tempFilename . '.tmp.' . $tag;
* Renames an image by copying and deleting.
* @param string $NewNameinput image filename
function renameImage($NewName) {
$Filename = dirname($this->ImageInfo['route']) . DIR_SLASH . $NewName;
copy($this->ImageInfo['route'], $Filename);
unlink($this->ImageInfo['route']);
* Returns the format of the image like GIF, JPG or PNG as an integer.
* @return string image format
return $this->ImageInfo['type'];
* Returns the image extension.
* @return string image extension
return $this->ImageInfo['ext'];
* Returns the image width.
* @return int image width
return $this->ImageInfo['width'];
* Returns the image height.
* @return int image height
return $this->ImageInfo['height'];
* Returns the image name after being converted to a nice version.
* @return string nice image filename
return $this->ImageInfo['nice_name'] . '.' . $this->ImageInfo['ext'];
* Returns the nice image filename with the custom suffix added.
* @param string $suffix suffix for image
* @return string nice image filename with custom suffix added
return $this->ImageInfo['nice_name'] . $suffix;
* Returns the image temp name. Possibly not useful at this point. This
* could change in the future.
* @return string image temp filename
return $this->ImageInfo['temp_name'];
|