Source for file NetPBM.php
Documentation is available at NetPBM.php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
* NetPBM implementation for Image_Transform package
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
* @package Image_Transform
* @author Peter Bowyer <peter@mapledesign.co.uk>
* @author Philippe Jausions <Philippe.Jausions@11abacus.com>
* @copyright 2002-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: NetPBM.php,v 1.21 2007/04/19 16:36:09 dufuz Exp $
* @link http://pear.php.net/package/Image_Transform
require_once 'Image/Transform.php';
require_once 'System.php';
* NetPBM implementation for Image_Transform package
* @package Image_Transform
* @subpackage Image_Transform_Driver_NetPBM
* @author Peter Bowyer <peter@mapledesign.co.uk>
* @author Philippe Jausions <Philippe.Jausions@11abacus.com>
* @copyright 2002-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @package_version@
* @link http://pear.php.net/package/Image_Transform
* @link http://netpbm.sourceforge.net/
* associative array commands to be executed
} // End function Image_NetPBM
if (!defined('IMAGE_TRANSFORM_NETPBM_PATH')) {
$path = dirname(System ::which ('pnmscale'))
define('IMAGE_TRANSFORM_NETPBM_PATH', $path);
if (!System ::which (IMAGE_TRANSFORM_NETPBM_PATH . 'pnmscale'
. ((OS_WINDOWS ) ? '.exe' : ''))) {
$this->isError(PEAR ::raiseError ('Couldn\'t find "pnmscale" binary',
} // End function Image_NetPBM
* @return bool|PEAR_ErrorTRUE or a PEAR_Error object on error
if (PEAR ::isError ($result)) {
* @param int $new_x New width
* @param int $new_y New height
* @param mixed $options Optional parameters
* @return true on success or PEAR Error object on error
function _resize($new_x, $new_y, $options = null )
// there's no technical reason why resize can't be called multiple
// times...it's just silly to do so
$scaleMethod = $this->_getOption('scaleMethod', $options, 'smooth');
$scale_x = $new_x / $this->img_x;
if ($scale_x == $new_y / $this->img_x
&& floor($scale_x) == $scale_x) {
if (System ::which (IMAGE_TRANSFORM_NETPBM_PATH .
. ((OS_WINDOWS ) ? '.exe' : ''))) {
IMAGE_TRANSFORM_NETPBM_PATH ,
return PEAR ::raiseError ('Couldn\'t find "pnmenlarge" binary',
IMAGE_TRANSFORM_NETPBM_PATH ,
'-nomix -width ' . ((int) $new_x)
. ' -height ' . ((int) $new_y));
IMAGE_TRANSFORM_NETPBM_PATH ,
'-width ' . ((int) $new_x) . ' -height '
// Smooth things if scaling by a factor more than 3
// (see pnmscale man page)
if ($new_x / $this->img_x > 3
|| $new_y / $this->img_y > 3 ) {
if (System ::which (IMAGE_TRANSFORM_NETPBM_PATH .
'pnmsmooth' . ((OS_WINDOWS ) ? '.exe' : ''))) {
IMAGE_TRANSFORM_NETPBM_PATH ,
return PEAR ::raiseError ('Couldn\'t find "pnmsmooth" binary',
* @param int $angle The angle to rotate the image through
* @return bool|PEAR_ErrorTRUE on success, PEAR_Error object on error
function rotate($angle, $options = null )
// For pnmrotate, we want to limit rotations from -45 to +45 degrees
// even if acceptable range is -90 to +90 (see pnmrotate man page)
// Bring image to that range by using pamflip
if ($angle > 45 && $angle < 315 ) {
if (!System ::which (IMAGE_TRANSFORM_NETPBM_PATH .
'pamflip' . ((OS_WINDOWS ) ? '.exe' : ''))) {
return PEAR ::raiseError ('Couldn\'t find "pamflip" binary',
IMAGE_TRANSFORM_NETPBM_PATH ,
'-rotate' . (360 - $quarters * 90 ));
$angle -= $quarters * 90;
if (!System ::which (IMAGE_TRANSFORM_NETPBM_PATH .
'pnmrotate' . ((OS_WINDOWS ) ? '.exe' : ''))) {
return PEAR ::raiseError ('Couldn\'t find "pnmrotate" binary',
$bgcolor = $this->_getColor('canvasColor', $options,
$scaleMethod = $this->_getOption('scaleMethod', $options, 'smooth');
if ($scaleMethod != 'pixel') {
IMAGE_TRANSFORM_NETPBM_PATH ,
'-background=' . $bgcolor . ' -' . (float) $angle);
IMAGE_TRANSFORM_NETPBM_PATH ,
'-background=' . $bgcolor . ' -noantialias -' . (float) $angle);
* @param int $width Cropped image width
* @param int $height Cropped image height
* @param int $x positive X-coordinate to crop at
* @param int $y positive Y-coordinate to crop at
* @return mixed TRUE or a PEAR error object on error
* @todo keep track of the new cropped size
function crop($width, $height, $x = 0 , $y = 0 )
if (!$this->intersects($width, $height, $x, $y)) {
|| $width != $this->img_x
|| $height != $this->img_y) {
if (!System ::which (IMAGE_TRANSFORM_NETPBM_PATH .
'pnmcut' . ((OS_WINDOWS ) ? '.exe' : ''))) {
return PEAR ::raiseError ('Couldn\'t find "pnmcut" binary',
IMAGE_TRANSFORM_NETPBM_PATH ,
. ' -width ' . ((int) $width)
. ' -height ' . ((int) $height));
* @param float $outputgamma
* @return mixed TRUE or a PEAR error object on error
function gamma($outputgamma = 1.0 ) {
if ($outputgamme != 1.0 ) {
if (!System ::which (IMAGE_TRANSFORM_NETPBM_PATH .
'pnmgamma' . ((OS_WINDOWS ) ? '.exe' : ''))) {
return PEAR ::raiseError ('Couldn\'t find "pnmgamma" binary',
IMAGE_TRANSFORM_NETPBM_PATH ,
* @return TRUE or PEAR Error object on error
if (!System ::which (IMAGE_TRANSFORM_NETPBM_PATH .
'pamflip' . ((OS_WINDOWS ) ? '.exe' : ''))) {
return PEAR ::raiseError ('Couldn\'t find "pamflip" binary',
IMAGE_TRANSFORM_NETPBM_PATH ,
* @return TRUE or PEAR Error object on error
if (!System ::which (IMAGE_TRANSFORM_NETPBM_PATH .
'pamflip' . ((OS_WINDOWS ) ? '.exe' : ''))) {
return PEAR ::raiseError ('Couldn\'t find "pamflip" binary',
IMAGE_TRANSFORM_NETPBM_PATH ,
* Converts an image into greyscale colors
* @return mixed TRUE or a PEAR error object on error
if (!System ::which (IMAGE_TRANSFORM_NETPBM_PATH .
'ppmtopgm' . ((OS_WINDOWS ) ? '.exe' : ''))) {
return PEAR ::raiseError ('Couldn\'t find "ppmtopgm" binary',
IMAGE_TRANSFORM_NETPBM_PATH ,
* @param array options Array contains options
* 'text' // The string to draw
* 'x' // Horizontal position
* 'y' // Vertical Position
* 'font' // Font to be used
* 'size' // Size of the fonts in pixel
* 'resize_first' // Tell if the image has to be resized
* // before drawing the text
if (!System ::which (IMAGE_TRANSFORM_NETPBM_PATH .
'ppmlabel' . ((OS_WINDOWS ) ? '.exe' : ''))) {
return PEAR ::raiseError ('Couldn\'t find "ppmlabel" binary',
// we ignore 'resize_first' since the more logical approach would be
// for the user to just call $this->_resize() _first_ ;)
$options = array ('colorFont' => $color);
$color = $this->_getColor('colorFont', $options, array (0 , 0 , 0 ));
IMAGE_TRANSFORM_NETPBM_PATH ,
'-angle ' . ((int) $angle)
. ' -size ' . ((float) $size)
. ' -y ' . ((int) ($y + $size))
* Image_Transform_Driver_NetPBM::_postProcess()
* @return string A chain of shell command
* @link http://netpbm.sourceforge.net/doc/directory.html
function _postProcess ($type, $quality)
IMAGE_TRANSFORM_NETPBM_PATH ,
if (!System ::which (IMAGE_TRANSFORM_NETPBM_PATH . 'ppmquant'
. ((OS_WINDOWS ) ? '.exe' : ''))) {
return PEAR ::raiseError ('Couldn\'t find "ppmquant" binary',
IMAGE_TRANSFORM_NETPBM_PATH ,
$program = 'ppmto' . $type;
$program = 'ppmto' . $type;
$program = 'pbmto' . $type;
$program = 'pamto' . $type;
$arg = '--quality=' . $quality;
$program = 'pnmto' . $type;
$program = 'pnmto' . $type;
if (!System ::which (IMAGE_TRANSFORM_NETPBM_PATH . $program
. ((OS_WINDOWS ) ? '.exe' : ''))) {
return PEAR ::raiseError (" Couldn't find \"$program\" binary" ,
IMAGE_TRANSFORM_NETPBM_PATH ,
* @param $filename string the name of the file to write to
* @param string $type (jpeg,png...);
* @return TRUE or PEAR Error object on error
function save($filename, $type = null , $quality = 75 )
$options['quality'] = $quality;
$quality = $this->_getOption('quality', $options, $quality);
$nullDevice = (OS_WINDOWS ) ? 'nul' : '/dev/null';
$cmd = $this->_postProcess ($type, $quality) . '> "' . $filename . '"';
exec($cmd . '2> ' . $nullDevice, $res, $exit);
return ($exit == 0 ) ? true : PEAR ::raiseError (implode('. ', $res),
* Display image without saving and lose changes
* @param string $type (jpeg,png...);
|