PHP Classes

File: imager.php

Recommend this page to a friend!
  Classes of Viktor Jenei   Imager   imager.php   Download  
File: imager.php
Role: Class source
Content type: text/plain
Description: Imager class
Class: Imager
Perform several operations to manipulate images
Author: By
Last change: * Optimization in: blur, blurgaussian, brightness, contrast, gamma,
grayscale, negate, sepia, sketch, smooth
* addAlpha: if you add alpha channel picture use that alpha, else the color component will be used
+ add new function: toPalette( $maxColor, $dither )
+ add new function: getChannel ( R-G-B, HSL, HSV, HSI ... )
+ add new function: getHistogramData
+ add new function: makeHistogram
+ add new function: transparency
+ add new function: createFromArray
+ add new function: imagefilterhueadjustment
Date: 12 years ago
Size: 50,073 bytes
 

Contents

Class file image Download
<?php /** * Imager, simply manipulate pictures. * Version: 1.13 * * Changelog: * 1.13 ( 2012-02-19 ) * * Optimization in: blur, blurgaussian, brightness, contrast, gamma, * grayscale, negate, sepia, sketch, smooth * * addAlpha: if you add alpha channel picture use that alpha, else the * color component will be used * + add new function: toPalette( $maxColor, $dither ) * + add new function: getChannel ( R-G-B, HSL, HSV, HSI ... ) * + add new function: getHistogramData * + add new function: makeHistogram * + add new function: transparency * + add new function: createFromArray * + add new function: imagefilterhueadjustment * 1.12 ( 2011-12-30 ) * * Lots of bugfixes with transparency images ( watermark, resize, rotate) * + code optimizations * 1.11 ( 2011-10-30 ) * + add some PHPDoc comment * + addImage function * + add exception to the save/load functions * * fix an input image error in darkness effect * + new effects: saturation, noise, scatter, pixelate * * @author Jenei Viktor Attila * @copyright 2010-2011 Jenei Viktor Attila * @package Imager * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @filesource */ abstract class imgLoaderSaver { protected $filename; abstract public function load( ); abstract public function save( &$imgres ); } class Channel { const RGB = 0; const RED = 1; const GREEN = 2; const BLUE = 3; const ALPHA = 4; const HSL = 5; const HSV = 6; const HSI = 7; const HSL2 = 8; const HSP = 9; const CCIR601 = 10; const ITU_R = 11; } class JPEG extends imgLoaderSaver { protected $quality = 85; public function __construct( $filename, $quality = 85 ) { $this->filename = $filename; $this->quality = $quality; } public function load( ) { if ( file_exists( $this->filename ) ) { return imagecreatefromjpeg( $this->filename ); } return null; } public function save( &$imgres ) { if ( file_exists( $this->filename ) ) { unlink( $this->filename ); } if ( !imagejpeg( $imgres, $this->filename, $this->quality ) ) { throw new Exception( 'notwriteable' ); } } } class PNG extends imgLoaderSaver { protected $quality = 6; public function __construct( $filename, $quality = 6 ) { $this->filename = $filename; $this->quality = $quality; } public function load( ) { if ( file_exists( $this->filename ) ) { $res = imagecreatefrompng( $this->filename ); return $res; } return null; } public function save( &$imgres ) { if ( file_exists( $this->filename ) ) { unlink( $this->filename ); } if ( !imagepng( $imgres, $this->filename, $this->quality ) ) { throw new Exception( 'notwriteable' ); } } } class GIF extends imgLoaderSaver { public function __construct( $filename ) { $this->filename = $filename; } public function load( ) { if ( file_exists( $this->filename ) ) { return imagecreatefromgif( $this->filename ); } return null; } public function save( &$imgres ) { if ( file_exists( $this->filename ) ) { unlink( $this->filename ); } if ( !imagegif( $imgres, $this->filename ) ) { throw new Exception( 'notwriteable' ); } } } class Canvas extends imgLoaderSaver { protected $width = 0; protected $height = 0; protected $color = 0; public function __construct( $width, $height, $fillcolor = array( 0, 0, 0) ) { $this->width = $width; $this->height= $height; $this->color = $fillcolor; } public function load( ) { $t = imagecreatetruecolor( $this->width, $this->height ); $col = imagecolorallocate( $t, $this->color[0], $this->color[1], $this->color[2] ); imagefilledrectangle( $t, 0, 0, $this->width, $this->height, $col ); return $t; } public function save( &$imgres ) { } } class AutoFileInput extends imgLoaderSaver { public function __construct( $filename ) { $this->filename = $filename; } public function load( ) { if ( file_exists( $this->filename ) ) { $image_info = getimagesize( $this->filename ); $img = null; switch( $image_info[2] ) { case 1: $img = new GIF( $this->filename ) ; break; case 2: $img = new JPEG( $this->filename ) ; break; case 3: $img = new PNG( $this->filename ) ; break; } if ( $img != null ) { return $img->load( ); } } throw new Exception( 'notsupportedimage' ); } public function save( &$imgres ) { } } class Transparency { public $transparent = false; public $alphachannel = false; public $color = array( 255, 255, 255 ); public function __construct( $typeof = null ) { if ( $typeof != null ) { if ( is_array( $typeof ) ) { $this->transparent = true; $this->color = $typeof; } else if ( is_bool( $typeof ) ) { $this->transparent = true; $this->alphachannel = true; } } } } class Imager { const TOP_LEFT = 0x00000001; const TOP_RIGHT = 0x00000002; const BOTTOM_LEFT = 0x00000003; const BOTTOM_RIGHT = 0x00000004; const CENTER = 0x00000005; const ABSOLUTE = 0x00000006; protected $fontPath = './'; protected $properties = array( 'width', 'height' ); protected $imgres = null; protected $transparencyinfo = null; private function rotateX( $x, $y, $theta ){ return $x * cos( $theta ) - $y * sin( $theta ); } private function rotateY( $x, $y, $theta ){ return $x * sin( $theta ) + $y * cos( $theta ); } public function __get( $k ) { if( array_key_exists( $k, $this->properties ) ) return $this->properties[ $k ]; } public function __set($k, $v) { $this->properties[$k] = $v; } public function getResource() { return $this->imgres; } public function getTransparencyInfo() { return $this->transparencyinfo; } public function setTransparencyInfo( $ti ) { $this->transparencyinfo = $ti; } protected function cloneTransparency( &$t, &$ti ) { if ( $ti->transparent ) { if ( $ti->alphachannel ) { imagealphablending( $t, false ); imagesavealpha( $t, true ); } else { list( $r, $g, $b ) = $ti->color; $clr = imagecolorallocate( $t, $r, $g, $b); imagecolortransparent( $t, $clr ); } } } public function transpColorToAlphaChannel( ) { $t = imagecreatetruecolor( $this->width, $this->height ); $ti = $this->getTransparencyInfo(); list( $ra, $ga, $ba ) = $ti->color; imagealphablending( $t, false ); imagesavealpha( $t, true ); for( $y = 0; $y < $this->height; $y++ ) { for( $x = 0; $x < $this->width; $x++ ) { $rgb = imagecolorat( $this->imgres, $x, $y ); $r = ( $rgb >> 16 ) & 0xFF; $g = ( $rgb >> 8 ) & 0xFF; $b = $rgb & 0xFF; if ( $ra == $r && $ga == $g && $ba == $b ) { $color = imagecolorallocatealpha( $t, $r, $g, $b, 127 ); } else { $color = imagecolorallocatealpha( $t, $r, $g, $b, 0 ); } imagesetpixel( $t, $x, $y, $color ); } } return new Imager( $t, new Transparency( true ) ); } public function __construct( $img = null, Transparency $transp = null ) { $this->transparencyinfo = $transp; if ( !is_null( $img ) ) { if ( $img instanceof Imager ) { $res = $img->getResource(); $this->imgres = clone $res; } else if( $img instanceof imgLoaderSaver ) { $this->imgres = $img->load(); if ( $this->imgres === null ) { throw new Exception( 'cannotload' ); } } else if ( is_resource( $img ) ) { $this->imgres = $img; } if ( $this->imgres != null ) { $this->width = imagesx( $this->imgres ); $this->height = imagesy( $this->imgres ); } else { /* throw an error */ } if ( $transp != null ) { if ( $transp->transparent ) { if ( $transp->alphachannel ) { imagealphablending( $this->imgres, false ); imagesavealpha( $this->imgres, true ); } else { list( $r, $g, $b ) = $transp->color; $clr = imagecolorallocate( $this->imgres, $r, $g, $b); imagecolortransparent( $this->imgres, $clr ); } } } } else { /* throw an error */ } } public function __destruct() { if ( is_resource( $this->imgres ) ) imagedestroy( $this->imgres ); } public function cloneObject( $withImage = true ) { $ti = $this->getTransparencyInfo(); $t = imagecreatetruecolor( $this->width, $this->height ); if ( $withImage ) { if ( $ti != null && $ti->transparent && $ti->alphachannel ) { imagealphablending( $t, false ); imagecopy( $t, $this->imgres, 0, 0, 0, 0, $this->width, $this->height); } else { imagecopymerge( $t, $this->imgres, 0, 0, 0, 0, $this->width, $this->height, 100 ); } } $this->cloneTransparency( $t, $ti ); return new Imager( $t, $ti ); } public function setFontPath( $pathName ) { $this->fontPath = $pathName; return $this; } public function getFontPath() { return $this->fontPath; } public function save( $img = null ) { if ( !is_null( $img ) ) { if ( $img instanceof Imager ) { } else if( $img instanceof imgLoaderSaver ) { $transp = $this->getTransparencyInfo(); if ( $transp->alphachannel ) { imagealphablending( $this->imgres, false ); imagesavealpha( $this->imgres, true ); } $img->save( $this->imgres ); } else { /* throw an error */ } } else { /* throw an error */ } return $this; } /** * Fill the image with a color * * @param array $color Red-Green-Blue values * @return Imager */ public function fill( $color = array( 0, 0, 0 ) ) { $img = $this->cloneObject(); $im = $img->imgres; //$this->cloneTransparency( $im, $img->getTransparencyInfo() ); $co = imagecolorallocate( $im, $color[0], $color[1], $color[2] ); imagefilledrectangle( $im, 0, 0, $this->width, $this->height, $co ); return new Imager( $im, $img->getTransparencyInfo() ); } /** * Make a thumbnail picture of image * * @param Imager $img the picture want to thumb * @param bool $crop true if you don't want background, default is false * @return Imager */ public function thumb( $img, $crop = false ) { if ( ! ( $img instanceof Imager ) ) $img = new Imager( $img, $this->getTransparencyInfo() ); $scale = min( $this->height / $img->height, $this->width / $img->width ); $nw = (int)ceil( $img->width * $scale ); $nh = (int)ceil( $img->height * $scale ); while ( $nw > $this->width ) $nw--; while ( $nh > $this->height ) $nh--; if ( $crop ) { return $img->resize( $nw, $nh ); } else { return $this->watermark( $img->resize( $nw, $nh ), Imager::CENTER ); } } /** * Add a picture to another * * @param Imager $img the picture want to add * @param int $x X offset * @param int $y Y offset * @return Imager */ public function addImage( $img, $x = 0, $y = 0 ) { if ( ! ( $img instanceof Imager ) ) $img = new Imager( $img, $this->getTransparencyInfo() ); $w = $this->width; $h = $this->height; if ( $this->width < ( $img->width + $x ) ) { $w = $img->width + $x; } if ( $this->height < ( $img->height + $y ) ) { $w = $img->height + $y; } $t = imagecreatetruecolor( $w, $h ); $backcolor = imagecolorallocatealpha( $t, 0, 0, 0, 127 ); imagefill( $t, 0, 0, imagecolorallocatealpha( $t, 0, 0, 0, 127 ) ); $im = new Imager( $t, new Transparency( true ) ); return $im->watermark( $this, Imager::ABSOLUTE, 0, 0 ) ->watermark( $img, Imager::ABSOLUTE, $x, $y ); } /** * Fill to image width (and size) * * @param Imager $img the picture want to fill * @param bool $crop true if you don't want background, default is true * @return Imager */ public function fillTo( $img, $crop = true ) { if ( ! ( $img instanceof Imager ) ) $img = new Imager( $img, $this->getTransparencyInfo() ); $scale = min( $this->height / $img->height, $this->width / $img->width ); if ( $crop ) { $scale = max( $this->height / $img->height, $this->width / $img->width ); } $nw = (int)ceil( $img->width * $scale ); $nh = (int)ceil( $img->height * $scale ); if ( $crop ) { return $img->resize( $nw, $nh )-> crop( ( $nw - $this->width ) / 2 , ( $nh - $this->height ) / 2, $this->width, $this->height ); } else { return $img->resize( $nw, $nh ); } } public function textRectangle( $str, $fontsize = 13, $font_file = 'arial.ttf', $angle = 0 ) { $textsize = imageftbbox( $fontsize, $angle, $this->fontPath . '/' . $font_file, $str ); $result = array( 'lower_left_x' => $textsize[0], 'lower_left_y' => $textsize[1], 'lower_right_x' => $textsize[2], 'lower_right_y' => $textsize[3], 'upper_right_x' => $textsize[4], 'upper_right_y' => $textsize[5], 'upper_left_x' => $textsize[6], 'upper_left_y' => $textsize[7] ); return $result; } public function drawText( $str, $x = 0, $y = 0, $shadow = false, $fontsize = 13, $angle = 0, array $fontcolor = array(), $font_file = 'arial.ttf', array $extra = array() ) { $img = $this->cloneObject(); $im = $img->imgres; $color = imagecolorallocate( $im, 0x00, 0x00, 0x00 ); if ( count( $fontcolor ) == 3 ) { $color = imagecolorallocate( $im, $fontcolor[0], $fontcolor[1], $fontcolor[2] ); } if ( $shadow ) { $shadow_text_color = imagecolorallocate( $im, 40, 40, 40 ); imagefttext( $im, $fontsize, $angle, $x + 1, $y + 1, $shadow_text_color, $font_file , $str); } imagefttext( $im, $fontsize, $angle, $x, $y, $color, $this->fontPath . '/' . $font_file, $str ); return $img; } public function drawRectangle( $x1, $y1, $x2, $y2, array $color = array(), $linesize = 1, $filled = false ) { $img = $this->cloneObject(); $im = $img->imgres; $rectcolor = imagecolorallocate( $im, 0xFF, 0xFF, 0xFF ); if ( count( $color ) == 3 ) { $rectcolor = imagecolorallocate( $im, $color[0], $color[1], $color[2] ); } if ( $filled ) { imagefilledrectangle( $im, $x1, $y1, $x2, $y2, $rectcolor ); } else { imagesetthickness( $im, $linesize ); imagerectangle( $im, $x1, $y1, $x2, $y2, $rectcolor ); } return $img; } public function fillColorToBorder( $start_x, $start_y, array $fill_color = array( 0xFF, 0xFF, 0xFF ), array $border_color = array( 0, 0, 0 ) ) { $img = $this->cloneObject(); $im = $img->imgres; $fill = imagecolorallocate( $im, 0xFF, 0xFF, 0xFF ); $border = imagecolorallocate( $im, 0, 0, 0 ); if ( count( $fill_color ) == 3 ) { $fill = imagecolorallocate( $im, $fill_color[0], $fill_color[1], $fill_color[2] ); } if ( count( $border_color ) == 3 ) { $border = imagecolorallocate( $im, $border_color[0], $border_color[1], $border_color[2] ); } imagefilltoborder( $im, $start_x, $start_y, $border, $fill ); return $img; } public function drawEllipse( $center_x, $center_y, $width, $height, $filled = false, $linesize = 1, array $color = array() ) { $img = $this->cloneObject(); $ocolor = imagecolorallocate( $img->imgres, 0xFF, 0xFF, 0xFF ); if ( count( $color ) == 3 ) { $ocolor = imagecolorallocate( $img->imgres, $color[0], $color[1], $color[2] ); } if ( $filled ) { imagefilledellipse( $img->imgres, $center_x, $center_y, $width, $height, $ocolor ); } else { imagesetthickness( $img->imgres, $linesize ); imageellipse( $img->imgres, $center_x, $center_y, $width, $height, $ocolor ); } return $img; } /* source: http://hu.php.net/manual/en/function.imageline.php */ public function drawLine( $x1, $y1, $x2, $y2, array $color = array(), $thick = 1 ) { /* this way it works well only for orthogonal lines imagesetthickness($image, $thick); return imageline($image, $x1, $y1, $x2, $y2, $color); */ $img = $this->cloneObject(); $icolor = imagecolorallocate( $img->imgres, 0, 0, 0 ); if ( count( $color ) == 3 ) { $icolor = imagecolorallocate( $img->imgres, $color[0], $color[1], $color[2] ); } if ( $thick == 1 ) { imageline( $img->imgres, $x1, $y1, $x2, $y2, $icolor ); } $t = $thick / 2 - 0.5; if ( $x1 == $x2 || $y1 == $y2 ) { imagefilledrectangle( $img->imgres, round( min( $x1, $x2 ) - $t ), round( min( $y1, $y2 ) - $t ), round( max( $x1, $x2 ) + $t ), round( max( $y1, $y2 ) + $t ), $icolor ); return $img; } $k = ( $y2 - $y1 ) / ( $x2 - $x1 ); //y = kx + q $a = $t / sqrt( 1 + pow( $k, 2 ) ); $points = array( round( $x1 - ( 1 + $k ) * $a ), round( $y1 + ( 1 - $k ) * $a ), round( $x1 - ( 1 - $k ) * $a ), round( $y1 - ( 1 + $k ) * $a ), round( $x2 + ( 1 + $k ) * $a ), round( $y2 - ( 1 - $k ) * $a ), round( $x2 + ( 1 - $k ) * $a ), round( $y2 + ( 1 + $k ) * $a ), ); imagefilledpolygon( $img->imgres, $points, 4, $icolor ); imagepolygon( $img->imgres, $points, 4, $icolor ); return $img; } public function drawPolygon( $image, array $points = array(), $filled = false, array $color = array(), $linesize = 1 ) { $img = $this->cloneObject(); $icolor = imagecolorallocate( $img->imgres, 0, 0, 0 ); if ( count( $color ) == 3 ) { $icolor = imagecolorallocate( $img->imgres, $color[0], $color[1], $color[2] ); } $poi = array(); foreach( $points as $k => $row ) { $poi[] = $row[ 'x' ]; $poi[] = $row[ 'y' ]; } if ( $filled ) { imagefilledpolygon( $img->imgres, $poi, count( $points ), $icolor ); } else { imagesetthickness( $img->imgres, $linesize ); imagepolygon( $img->imgres, $poi, count( $points ), $icolor ); } return $img; } public function drawPolygonSoft( array $points = array(), $filled = false, array $color = array(), $linesize = 1 ) { $img = $this->cloneObject(); foreach( $points as $k => $row ) { if ( $k > 0 ) { $img->drawLine( $points[ $k - 1 ][ 'x' ], $points[ $k - 1 ][ 'y' ], $row[ 'x' ], $row[ 'y' ], $color, $linesize ); } } $img->drawLine( $points[ count( $points ) - 1 ][ 'x' ], $points[ count( $points ) - 1 ][ 'y' ], $points[0][ 'x' ], $points[0][ 'y' ], $color, $linesize ); return $img; } public function drawArc( $center_x, $center_y, $width, $height, $start_degree, $end_degree, $filled = false, $linesize = 1, array $color = array() ) { $img = $this->cloneObject(); $ocolor = imagecolorallocate( $img->imgres, 0, 0, 0 ); if ( count( $color ) == 3 ) { $ocolor = imagecolorallocate( $img->imgres, $color[0], $color[1], $color[2] ); } if ( $filled ) { imagefilledarc( $img->imgres, $center_x, $center_y, $width, $height, $start_degree, $end_degree, $ocolor, IMG_ARC_PIE); } else { imagesetthickness( $img->imgres, $linesize ); imagearc( $img->imgres, $center_x, $center_y, $width, $height, $start_degree, $end_degree, $ocolor ); } return $img; } /* http://hu.php.net/manual/en/function.imageline.php */ protected function bezier_cubic_interpolation( $points, $steps ){ $t = 1 / $steps; $temp = $t * $t; $ret = array(); $f = $points[0]; $fd = 3 * ( $points[1] - $points[0] ) * $t; $fdd_per_2= 3 * ( $points[0] - 2 * $points[1] + $points[2] ) * $temp; $fddd_per_2 = 3 * ( 3*( $points[1] - $points[2] ) + $points[3] - $points[0] ) * $temp * $t; $fddd = $fddd_per_2 + $fddd_per_2; $fdd = $fdd_per_2 + $fdd_per_2; $fddd_per_6 = $fddd_per_2 * ( 1.0 / 3 ); for ( $loop=0; $loop < $steps; $loop++ ) { array_push( $ret, $f ); $f = $f + $fd + $fdd_per_2 + $fddd_per_6; $fd = $fd + $fdd + $fddd_per_2; $fdd = $fdd + $fddd; $fdd_per_2 = $fdd_per_2 + $fddd_per_2; } return $ret; } public function bezier( array $points = array(), $steps, $linesize = 1, array $color = array() ) { $x = array(); $y = array(); foreach( $points as $point ) { array_push( $x, $point[ 'x' ] ); array_push( $y, $point[ 'y' ] ); } $bx = $this->bezier_cubic_interpolation( $x, $steps ); $by = $this->bezier_cubic_interpolation( $y, $steps ); $im = imagecreatetruecolor( $this->width, $this->height ); imagecopyresampled( $im, $this->imgres, 0, 0, 0, 0, $this->width, $this->height, $this->width, $this->height ); $img = new Imager( $im, $this->getTransparencyInfo() ); $ocolor = imagecolorallocate( $im, 233, 14, 91); if ( count( $color ) == 3 ) { $ocolor = imagecolorallocate( $im, $color[0], $color[1], $color[2] ); } imagesetthickness( $im, $linesize ); for( $i = 0; $i < $steps - 1; $i++ ) { imageline( $im, $bx[ $i ], $by[ $i ], $bx[ $i + 1 ], $by[ $i + 1 ], $ocolor ); } return $img; } /** * Add alpha transparency layer image to the image * * @param Imager $img the picture want to use as Alpha * @return Imager */ public function addAlpha( $img ) { if ( ! ($img instanceof Imager) ) $img = new Imager( $img ); $t = imagecreatetruecolor( $this->width, $this->height ); imagealphablending( $t, false ); $alphid = $img->getResource(); $tid = $this->getResource(); $transp = $img->getTransparencyInfo(); for($y=0; $y < $this->height; $y++) { for( $x=0; $x < $this->width; $x++) { $alpha = 0; // if picture has Alpha channel, use it if ( $transp->alphachannel ) { $color = imagecolorsforindex( $alphid, imagecolorat( $alphid, $x, $y ) ); $alpha = $color[ 'alpha' ]; } else { // use the grayscaled picture blue value $blue = (int)( ( imagecolorat( $alphid, $x, $y ) & 0xFF ) / 2 ); $alpha = 127 - $blue; } $rgb = imagecolorat( $tid, $x, $y ); $r = ( $rgb >> 16 ) & 0xFF; $g = ( $rgb >> 8 ) & 0xFF; $b = $rgb & 0xFF; $ncolor = imagecolorallocatealpha( $t, $r, $g, $b, $alpha ); imagesetpixel( $t, $x, $y, $ncolor ); } } return new Imager( $t, new Transparency( true ) ); } /** * Scaleto image to width, height, or resize to a box (with the default propotion) * * @param string $method width, height, box * @param array $value only used when the $method is box, the array looked like as array( 100, 200 ) * @return Imager */ public function scaleTo( $method = 'width', $value ) { $scale = 1; if ( $method == 'width' ) { $scale = $value / $this->width ; } else if ( $method == 'height' ){ $scale = $value / $this->height; } else if ( $method == 'box' && is_array( $value ) ) { $scale1 = $value[0] / $this->width; $scale2 = $value[1] / $this->height; $scale = min( $scale1, $scale2 ); } $nw = (int)ceil( $this->width * $scale ); $nh = (int)ceil( $this->height * $scale ); return $this->resize( $nw, $nh ); } /** * Resize an image to a width-height pair * * @param int $width New width * @param int $height New height * @return Imager */ public function resize( $width, $height ) { $t = imagecreatetruecolor( $width, $height ); $this->cloneTransparency( $t, $this->getTransparencyInfo() ); imagecopyresampled( $t, $this->imgres, 0, 0, 0, 0, $width, $height, $this->width, $this->height ); return new Imager( $t, $this->getTransparencyInfo() ); } /** * Crop an image * * @param int $x X offset * @param int $y Y offset * @param int $width Width * @param int $height Height * @return Imager */ public function crop( $x, $y, $w, $h ) { if($x + $w > $this->width) $w = $this->width - $x; if($y + $h > $this->height) $h = $this->height - $y; if($w <= 0 || $h <= 0) return false; $t = imagecreatetruecolor( $w, $h ); $this->cloneTransparency( $t, $this->getTransparencyInfo() ); $ti = $this->getTransparencyInfo(); if ( $ti != null && $ti->transparent && $ti->alphachannel ) { imagecopy( $t, $this->imgres, 0, 0, $x, $y, $w, $h ); } else { imagecopymerge( $t, $this->imgres, 0, 0, $x, $y, $w, $h, 100 ); } return new Imager( $t, $this->getTransparencyInfo() ); } /** * Flip horizontally * @return Imager */ public function flipH() { $img = $this->cloneObject(); imagecopyresampled( $img->imgres, $this->imgres, 0, 0, ( $this->width-1 ), 0, $this->width, $this->height, 0-$this->width, $this->height ); return $img; } /** * Flip vertically * @return Imager */ public function flipV() { $img = $this->cloneObject(); imagecopyresampled( $img->imgres, $this->imgres, 0, 0, 0, ( $this->height-1 ), $this->width, $this->height, $this->width, 0-$this->height ); return $img; } /** * Rotate a picture with angle (and background color) * @param double $degree Rotation degree * @param array $color Background color (RGB), default is black * @return Imager */ public function rotate( $degree, $color = array( 0,0,0 ), $ignore_transparent = 0 ) { $img = $this->cloneObject(); $backcolor = imagecolorallocatealpha( $img->imgres, $color[0], $color[1], $color[2], 127 ); $t = imagerotate( $img->imgres, $degree, $backcolor, $ignore_transparent ); if ( $ignore_transparent == 0 ) { imagesavealpha( $t, true ); } return new Imager( $t, new Transparency( true ) ); } /* very slow (getpixel, setpixel), but correct alternative to rotate pic ( source from internet ) */ public function rotate2( $degree, $color = array( 0, 0, 0 ) ) { $srcImg = $this->imgres; $angle = $degree; $bgcolor = ( $color[0] << 16 ) + ( $color[1] << 8 ) + $color[2]; $ignore_transparent = 0; $srcw = imagesx( $srcImg ); $srch = imagesy( $srcImg ); $angle %= 360; $angle = -$angle; if($angle == 0) { if ( $ignore_transparent == 0 ) { imagesavealpha( $srcImg, true ); } return $srcImg; } $theta = deg2rad ( $angle ); if ( ( abs( $angle ) == 90 ) || ( abs( $angle ) == 270 ) ) { $width = $srch; $height = $srcw; if ( ( $angle == 90 ) || ( $angle == -270 ) ) { $minX = 0; $maxX = $width; $minY = -$height+1; $maxY = 1; } else if ( ( $angle == -90 ) || ( $angle == 270 ) ) { $minX = -$width+1; $maxX = 1; $minY = 0; $maxY = $height; } } else if ( abs( $angle ) === 180 ) { $width = $srcw; $height = $srch; $minX = -$width+1; $maxX = 1; $minY = -$height+1; $maxY = 1; } else { $temp = array ( rotateX( 0, 0, 0-$theta ), rotateX( $srcw, 0, 0-$theta ), rotateX( 0, $srch, 0-$theta ), rotateX( $srcw, $srch, 0-$theta ) ); $minX = floor (min( $temp ) ); $maxX = ceil( max( $temp ) ); $width = $maxX - $minX; // the height of the destination image. $temp = array ( rotateY( 0, 0, 0-$theta ), rotateY( $srcw, 0, 0-$theta ), rotateY( 0, $srch, 0-$theta ), rotateY( $srcw, $srch, 0-$theta ) ); $minY = floor( min( $temp ) ); $maxY = ceil( max( $temp ) ); $height = $maxY - $minY; } $destimg = imagecreatetruecolor( $width, $height ); if ( $ignore_transparent == 0 ) { imagefill( $destimg, 0, 0, imagecolorallocatealpha( $destimg, 255,255, 255, 127 ) ); imagesavealpha( $destimg, true ); } for( $x = $minX; $x < $maxX; $x++ ) { for( $y = $minY; $y < $maxY; $y++ ) { // fetch corresponding pixel from the source image $srcX = round( rotateX( $x, $y, $theta ) ); $srcY = round( rotateY( $x, $y, $theta ) ); if( $srcX >= 0 && $srcX < $srcw && $srcY >= 0 && $srcY < $srch ) { $color = imagecolorat( $srcImg, $srcX, $srcY ); } else { $color = $bgcolor; } imagesetpixel( $destimg, $x-$minX, $y-$minY, $color ); } } return new Imager( $destimg, $this->getTransparencyInfo() ); } /** * Add a watermark image to the base image * * @param Imager $img the picture want to add * @param integer $direction where will be the watermark at the picture * @param integer $x X offset direction, when you use ABSOULUTE direction * @param integer $y Y offset direction, when you use ABSOULUTE direction * @return Imager */ public function watermark( $img, $direction = Imager::BOTTOM_RIGHT, $x = 0, $y = 0 ) { $img_ti = $img->getTransparencyInfo(); $this_ti = $this->getTransparencyInfo(); $alpharesize = false; if ( $img_ti != null && $img_ti->transparent && $img_ti->alphachannel ) { $alpharesize = true; } $alphaimg = false; if ( $this_ti != null && $this_ti->transparent && $this_ti->alphachannel ) { $alphaimg = true; } if ( ! ($img instanceof Imager) ) $img = new Imager( $img ); $t = imagecreatetruecolor( $this->width, $this->height ); if ( $alpharesize && $alphaimg ) { imagealphablending( $t, false ); imagesavealpha( $t, true ); } imagecopyresampled( $t, $this->imgres, 0, 0, 0, 0, $this->width, $this->height, $this->width, $this->height ); if ( $alpharesize && $alphaimg ) { imagealphablending( $t, true ); } $wmark_width = $img->width; $wmark_height = $img->height; switch( $direction ) { case Imager::CENTER : if ( $alpharesize ) { imagecopy( $t, $img->getResource(), ( $this->width - $wmark_width ) / 2, ( $this->height - $wmark_height ) / 2, 0, 0, $wmark_width, $wmark_height ); } else { imagecopymerge( $t, $img->getResource(), ( $this->width - $wmark_width ) / 2, ( $this->height - $wmark_height ) / 2, 0, 0, $wmark_width, $wmark_height, 100 ); } break; case Imager::TOP_LEFT : if ( $alpharesize ) { imagecopy( $t, $img->getResource(), 0, 0, 0, 0, $wmark_width, $wmark_height ); } else { imagecopymerge( $t, $img->getResource(), 0, 0, 0, 0, $wmark_width, $wmark_height, 100 ); } break; case Imager::TOP_RIGHT : if ( $alpharesize ) { imagecopy( $t, $img->getResource(), $this->width - $wmark_width, 0, 0, 0, $wmark_width, $wmark_height ); } else { imagecopymerge( $t, $img->getResource(), $this->width - $wmark_width, 0, 0, 0, $wmark_width, $wmark_height, 100 ); } break; case Imager::BOTTOM_LEFT : if ( $alpharesize ) { imagecopy( $t, $img->getResource(), 0, $this->height - $wmark_height, 0, 0, $wmark_width, $wmark_height ); } else { imagecopymerge( $t, $img->getResource(), 0, $this->height - $wmark_height, 0, 0, $wmark_width, $wmark_height, 100 ); } break; case Imager::ABSOLUTE : if ( $alpharesize ) { imagecopy( $t, $img->getResource(), $x, $y, 0, 0, $wmark_width, $wmark_height ); } else { imagecopymerge( $t, $img->getResource(), $x, $y, 0, 0, $wmark_width, $wmark_height, 100 ); } break; default: case Imager::BOTTOM_RIGHT : if ( $alpharesize ) { imagecopy( $t, $img->getResource(), $this->width - $wmark_width, $this->height - $wmark_height, 0, 0, $wmark_width, $wmark_height ); } else { imagecopymerge( $t, $img->getResource(), $this->width - $wmark_width, $this->height - $wmark_height, 0, 0, $wmark_width, $wmark_height, 100 ); } break; } return new Imager( $t, $this->getTransparencyInfo() ); } /** * Add darkness to the picture * * @param integer $amount Amount of the darkness * @return Imager */ public function darkness( $amount = 40 ) { $img = $this->cloneObject( false ); for( $y = 0; $y < $this->height; $y++ ) { for( $x = 0; $x < $this->width; $x++ ) { $rgb = imagecolorat( $this->imgres, $x, $y ); $alpha = $rgb >> 24; $r = ( $rgb >> 16 ) & 0xFF; $g = ( $rgb >> 8 ) & 0xFF; $b = $rgb & 0xFF; $nr = min( 255, max( $r - $r * $amount / 255, 0 ) ); $ng = min( 255, max( $g - $g * $amount / 255, 0 ) ); $nb = min( 255, max( $b - $b * $amount / 255, 0 ) ); $ncolor = imagecolorallocatealpha( $img->imgres, $nr, $ng, $nb, $alpha ); imagesetpixel( $img->imgres, $x, $y, $ncolor ); } } return $img; } public function saturation( $amount = 90 ) { $img = $this->cloneObject( false ); for( $y = 0; $y < $this->height; $y++ ) { for( $x = 0; $x < $this->width; $x++ ) { $rgb = imagecolorat( $this->imgres, $x, $y ); $alpha = $rgb >> 24; $r = ( $rgb >> 16 ) & 0xFF; $g = ( $rgb >> 8 ) & 0xFF; $b = $rgb & 0xFF; $gray = ( $r + $g + $b ) / 3 ; $nr = min( 255, max( $gray + ( ( $r - $gray ) * $amount / 255 ), 0 ) ); $ng = min( 255, max( $gray + ( ( $g - $gray ) * $amount / 255 ), 0 ) ); $nb = min( 255, max( $gray + ( ( $b - $gray ) * $amount / 255 ), 0 ) ); $ncolor = imagecolorallocatealpha( $img->imgres, $nr, $ng, $nb, $alpha ); imagesetpixel( $img->imgres, $x, $y, $ncolor ); } } return $img; } /** * Add random noise to the picture * * @return Imager */ public function noise() { $img = $this->cloneObject(); for( $y = 0; $y < $this->height; $y++ ) { for( $x = 0; $x < $this->width; $x++ ) { if ( rand( 0, 1 ) == 1 ) { $rgb = imagecolorat( $this->imgres, $x, $y ); $alpha = $rgb >> 24; $red = ( $rgb >> 16 ) & 0xFF; $green = ( $rgb >> 8 ) & 0xFF; $blue = $rgb & 0xFF; $modifier = rand( -20, 20 ); $red += $modifier; $green += $modifier; $blue += $modifier; if ( $red > 255 ) $red = 255; if ( $green > 255 ) $green = 255; if ( $blue > 255 ) $blue = 255; if ( $red < 0 ) $red = 0; if ( $green < 0 ) $green = 0; if ( $blue < 0 ) $blue = 0; $ncolor = imagecolorallocatealpha( $img->imgres, $nr, $ng, $nb, $alpha ); imagesetpixel( $img->imgres, $x, $y, $ncolor ); } } } return $img; } public function scatter() { $img = $this->cloneObject( true ); for( $y = 0; $y < $this->height; ++$y ) { for( $x = 0; $x < $this->width; ++$x ) { $distx = rand( -4, 4 ); $disty = rand( -4, 4 ); if ( ( $x + $distx ) >= $this->width ) continue; if ( ( $x + $distx ) < 0 ) continue; if ( ( $y + $disty ) >= $this->height ) continue; if ( ( $y + $disty ) < 0 ) continue; $oldcol = imagecolorat( $this->imgres, $x, $y ); $newcol = imagecolorat( $this->imgres, $x + $distx, $y + $disty ); imagesetpixel( $img->imgres, $x, $y, $newcol); imagesetpixel( $img->imgres, $x + $distx, $y + $disty, $oldcol ); } } return $img; } /** * Pixelate the image * * @param int $blocksize * @return Imager */ public function pixelate( $blocksize = 12 ) { $img = $this->cloneObject(); for( $y = 0; $y < $this->height; $y += $blocksize ) { for( $x = 0; $x < $this->width; $x += $blocksize ) { $rgb = imagecolorat( $this->imgres, $x, $y ); imagefilledrectangle( $img->imgres, $x, $y, $x + $blocksize - 1, $y + $blocksize - 1, $rgb ); } } return $img; } /* Some imagefiler effects */ public function imagefilterhueadjustment( array $newColor ) { $img = $this->cloneObject( false ); $rgb = $newColor[0] + $newColor[1] + $newColor[2]; $col = array( $newColor[0] / $rgb, $newColor[2] / $rgb, $newColor[1] / $rgb ); for( $x = 0; $x < $img->width; $x++ ) { for( $y = 0; $y < $img->height; $y++ ) { $color = imagecolorsforindex( $this->imgres, imagecolorat( $this->imgres, $x, $y ) ); $newR = $color[ 'red' ] * $col[0] + $color[ 'green' ] * $col[1] + $color[ 'blue' ] * $col[2]; $newG = $color[ 'red' ] * $col[2] + $color[ 'green' ] * $col[0] + $color[ 'blue' ] * $col[1]; $newB = $color[ 'red' ] * $col[1] + $color[ 'green' ] * $col[2] + $color[ 'blue' ] * $col[0]; $ncolor = imagecolorallocatealpha( $img->imgres, $newR, $newG, $newB, $colro[ 'alpha' ] ); imagesetpixel( $img->imgres, $x, $y, $ncolor ); } } return $img; } public function blur() { $img = $this->cloneObject(); imagefilter( $img->imgres, IMG_FILTER_SELECTIVE_BLUR ); return $img; } public function blurgaussian() { $img = $this->cloneObject(); imagefilter( $img->imgres, IMG_FILTER_GAUSSIAN_BLUR ); return $img; } public function brightness( $level = 10 ) { $img = $this->cloneObject(); imagefilter( $img->imgres, IMG_FILTER_BRIGHTNESS, $level ); return $img; } public function contrast( $level = 10 ) { $img = $this->cloneObject(); imagefilter( $img->imgres, IMG_FILTER_CONTRAST, $level ); return $img; } public function gamma( $from = 1.0, $to = 1.537 ) { $img = $this->cloneObject(); imagegammacorrect( $img->imgres, $from, $to ); return $img; } public function grayscale() { $img = $this->cloneObject(); imagefilter( $img->imgres, IMG_FILTER_GRAYSCALE ); return $img; } public function negate() { $img = $this->cloneObject(); imagefilter( $img->imgres, IMG_FILTER_NEGATE ); return $img; } public function sepia() { $img = $this->cloneObject(); imagefilter( $img->imgres, IMG_FILTER_GRAYSCALE ); imagefilter( $img->imgres, IMG_FILTER_COLORIZE, 112, 66, 20 ); return $img; } public function sketch() { $img = $this->cloneObject(); imagefilter( $img->imgres, IMG_FILTER_MEAN_REMOVAL ); return $img; } public function smooth( $level = 10 ) { $img = $this->cloneObject(); imagefilter( $img->imgres, IMG_FILTER_SMOOTH, $level ); return $img; } public function multiplyColor( $color = array( 255, 0, 0 ) ) { $img = $this->cloneObject(); //get opposite color $opposite = array( 255 - $color[ 0 ], 255 - $color[ 1 ], 255 - $color[ 2 ] ); //now we subtract the opposite color from the image imagefilter( $img->imgres, IMG_FILTER_COLORIZE, -$opposite[ 0 ], -$opposite[ 1 ], -$opposite[ 2 ] ); return $img; } public function colorScale(array $color){ $img = $this->cloneObject(); imagefilter( $img->imgres, IMG_FILTER_GRAYSCALE ); $luminance = ( $color[ 0 ] + $color[ 1 ] + $color[ 2 ] ) / 3; // average luminance added by the color $brightnessCorrection = $luminance / 3; // quantity of brightness to correct for each channel if( $luminance < 127 ){ $brightnessCorrection -= 127 / 3; // color is dark so we have to negate the brightness correction } imagefilter( $img->imgres, IMG_FILTER_COLORIZE, $color[ 0 ] - $luminance, $color[ 1 ] - $luminance, $color[ 2 ] - $luminance ); imagefilter( $img->imgres, IMG_FILTER_BRIGHTNESS, $brightnessCorrection ); return $img; } public function threshold( $val ) { $img = $this->cloneObject(); $gray = $this->grayscale(); for( $y = 0; $y < $this->height; $y++ ) { for( $x = 0; $x < $this->width; $x++ ) { $color = imagecolorsforindex( $img->imgres, imagecolorat( $img->imgres, $x, $y ) ); $b = ( $color[ 'blue' ] < $val ) ? 0 : 255; $ncolor = imagecolorallocatealpha( $img->imgres, $b, $b, $b, $color[ 'alpha' ] ); imagesetpixel( $img->imgres, $x, $y, $ncolor ); } } return $img; } public function autothreshold() { /* ISOData algorithm to detect the optimal threshold value */ $freq = array_fill( 0, 255, 0 ); $img = $this->cloneObject(); $gray = $this->grayscale(); for( $y = 0; $y < $this->height; $y++ ) { for( $x = 0; $x < $this->width; $x++ ) { $color = imagecolorsforindex( $img->imgres, imagecolorat( $img->imgres, $x, $y ) ); $freq[ $color[ 'blue' ] ]++; } } /* ISOData alg. */ $tprev = $nu = $jk = $bk = 0; $T = 128; $pixelnum = $this->width * $this->height; foreach( $freq as $i => $val ) { $nu += (double)( $val * $i ) / $pixelnum; } while( $tprev != $T ) { $bt = $nut = 0; for ( $i = 0; $i <= $T; $i++ ) { $bt += (double)( $freq[ $i ] ) / $pixelnum; $nut += (double)( $freq[ $i ] * $i ) / $pixelnum; } $jk = $nut / $bt; $bk = (double)( $nu - $nut ) / ( 1 - $bt ); $tprev = $T; $T = floor( (double)( $jk + $bk ) / 2 ); } return $img->threshold( $T ); } public function blurgaussian2() { $matrix = array( array( 1, 2, 1 ), array( 2, 4, 2 ), array( 1, 2, 1 ) ); $divisor = 16; $offset = 0; $img = $this->cloneObject(); imageconvolution( $img->imgres, $matrix, $divisor, $offset ); return $img; } public function emboss() { $matrix = array( array( 2, 0, 0 ), array( 0, -1, 0 ), array( 0, 0, -1 ) ); $divisor = 1; $offset = 127; $img = $this->cloneObject(); imageconvolution( $img->imgres, $matrix, $divisor, $offset ); return $img; } public function embosssoft() { $matrix = array( array( 1, 0, 0 ), array( 0, 0, 0 ), array( 0, 0, -1 ) ); $divisor = 1; $offset = 127; $img = $this->cloneObject(); imageconvolution( $img->imgres, $matrix, $divisor, $offset ); return $img; } public function edgeTopDown() { $matrix = array( array( 1, 1, 1 ), array( 1, -2, 1 ), array( -1, -1, -1 ) ); $divisor = 1; $offset = 0; $img = $this->cloneObject(); imageconvolution( $img->imgres, $matrix, $divisor, $offset ); return $img; } public function edgeHorizontal() { $matrix = array( array( -1, -1, -1 ), array( 2, 2, 2 ), array( -1, -1, -1 ) ); $divisor = 1; $offset = 0; $img = $this->cloneObject(); imageconvolution( $img->imgres, $matrix, $divisor, $offset ); return $img; } public function edgeVertical() { $matrix = array( array( -1, 2, -1 ), array( -1, 2, -1 ), array( -1, 2, -1 ) ); $divisor = 1; $offset = 0; $img = $this->cloneObject(); imageconvolution( $img->imgres, $matrix, $divisor, $offset ); return $img; } public function edgeLeftDiagonal() { $matrix = array( array( 2, -1, -1 ), array( -1, 2, -1 ), array( -1, -1, 2 ) ); $divisor = 1; $offset = 0; $img = $this->cloneObject(); imageconvolution( $img->imgres, $matrix, $divisor, $offset ); return $img; } public function edgeRightDiagonal() { $matrix = array( array( -1, -1, 2 ), array( -1, 2, -1 ), array( 2, -1, -1 ) ); $divisor = 1; $offset = 0; $img = $this->cloneObject(); imageconvolution( $img->imgres, $matrix, $divisor, $offset ); return $img; } public function edgeEnhance() { $matrix = array( array( 0, -1, 0 ), array( -1, 5, -1 ), array( 0, -1, 0 ) ); $divisor = 1; $offset = 0; $img = $this->cloneObject(); imageconvolution( $img->imgres, $matrix, $divisor, $offset ); return $img; } public function hipass() { $matrix = array( array( -1, -1, -1 ), array( -1, 9, -1 ), array( -1, -1, -1 ) ); $divisor = 1; $offset = 0; $img = $this->cloneObject(); imageconvolution( $img->imgres, $matrix, $divisor, $offset ); return $img; } public function laplace() { $matrix = array( array( -1, -1, -1 ), array( -1, 8, -1 ), array( -1, -1, -1 ) ); $divisor = 1; $offset = 0; $img = $this->cloneObject(); imageconvolution( $img->imgres, $matrix, $divisor, $offset ); return $img; } public function sharpen() { $matrix = array( array( -1, -1, -1 ), array( -1, 16, -1 ), array( -1, -1, -1 ) ); $divisor = 8; $offset = 0; $img = $this->cloneObject(); imageconvolution( $img->imgres, $matrix, $divisor, $offset ); return $img; } public function soften() { $matrix = array( array( 2, 2, 2 ), array( 2, 0, 2 ), array( 2, 2, 2 ) ); $divisor = 16; $offset = 0; $img = $this->cloneObject(); imageconvolution( $img->imgres, $matrix, $divisor, $offset ); return $img; } public function softenLess() { $matrix = array( array( 0, 1, 0 ), array( 1, 2, 1 ), array( 0, 1, 0 ) ); $divisor = 6; $offset = 0; $img = $this->cloneObject(); imageconvolution( $img->imgres, $matrix, $divisor, $offset ); return $img; } public function sobelhorizontal() { $matrix = array( array( -1, -2, -1 ), array( 0, 0, 0 ), array( 1, 2, 1 ) ); $divisor = 1; $offset = 0; $img = $this->cloneObject(); imageconvolution( $img->imgres, $matrix, $divisor, $offset ); return $img; } public function sobelvertical() { $matrix = array( array( -1, 0, 1 ), array( -2, 0, 2 ), array( -1, 0, 1 ) ); $divisor = 1; $offset = 0; $img = $this->cloneObject(); imageconvolution( $img->imgres, $matrix, $divisor, $offset ); return $img; } public function arithmeticmean() { $matrix = array( array( 1/9, 1/9, 1/9 ), array( 1/9, 1/9, 1/9 ), array( 1/9, 1/9, 1/9 ) ); $divisor = 1; $offset = 0; $img = $this->cloneObject(); imageconvolution( $img->imgres, $matrix, $divisor, $offset ); return $img; } public function convolution( array $matrix, $divisor, $offset ) { $img = $this->cloneObject(); imageconvolution( $img->imgres, $matrix, $divisor, $offset ); return $img; } public function toPalette( $maxNumColor, $dither = false ) { $img = $this->cloneObject(); imagetruecolortopalette( $img->imgres, $dither, $maxNumColor ); return $img; } /** * Get the image component values * * @param $channel : 0 : RGB, 1 : red, 2 : green, 3 : blue, 4 : alpha ... * @return array */ public function getChannel( $channel = Channel::RGB ) { $ret = array(); for( $y = 0; $y < $this->height; $y++ ) { for( $x = 0; $x < $this->width; $x++ ) { $color = imagecolorsforindex( $this->imgres, imagecolorat( $this->imgres, $x, $y ) ); switch( $channel ) { case Channel::RGB : $ret[ $y ][ $x ] = $color; break; case Channel::RED : $ret[ $y ][ $x ] = $color[ 'red' ]; break; case Channel::GREEN : $ret[ $y ][ $x ] = $color[ 'green' ]; break; case Channel::BLUE : $ret[ $y ][ $x ] = $color[ 'blue' ]; break; case Channel::ALPHA : $ret[ $y ][ $x ] = $color[ 'alpha' ]; break; case Channel::HSL : unset( $color[ 'alpha' ] ); $ret[ $y ][ $x ] = ( max( $color ) + min( $color ) ) / 2; break; case Channel::HSV : unset( $color[ 'alpha' ] ); $ret[ $y ][ $x ] = max( $color ); break; case Channel::HSI : unset( $color[ 'alpha' ] ); $ret[ $y ][ $x ] = array_sum( $color ) / 3; break; case Channel::HSL2 : $ret[ $y ][ $x ] = ( 3 * $color[ 'red' ] + 6 * $color[ 'green' ] + $color[ 'blue' ] ) / 10; break; case Channel::HSP : $ret[ $y ][ $x ] = round( sqrt( 0.299 * $color[ 'red' ] * $color[ 'red' ] + 0.587 * $color[ 'green' ] * $color[ 'green' ] + 0.114 * $color[ 'blue' ] * $color[ 'blue' ] ) ); break; case Channel::CCIR601 : $ret[ $y ][ $x ] = (int)( 0.299 * $color[ 'red' ] + 0.587 * $color[ 'green' ] + 0.114 * $color[ 'blue' ] ); break; case Channel::ITU_R : $ret[ $y ][ $x ] = (int)( 0.2126 * $color[ 'red' ] + 0.7152 * $color[ 'green' ] + 0.0722 * $color[ 'blue' ] ); break; } } } return $ret; } /** * Get the image channel component statistic * * @param $channel * @return Imager */ public function getHistogramData( $channel = Channel::RED ) { if ( $channel == Channel::RGB ) { throw new Exception( 'only one component value supported' ); } $stats = array_fill( 0, 256, 0 ); $channels = $this->getChannel( $channel ); foreach( $channels as $row ) { foreach( $row as $pixel ) { $stats[ $pixel ]++; } } return $stats; } /** * Make an alphablended channel histogram with the given size and color. * * @param int $channel * @param int $width * @param int $height * @param array $color * @param int $lineHeight * @return Imager */ public function makeHistogram( $channel = Channel::RED, $width, $height, array $color = array( 133, 90, 130 ), $lineHeight = 1 ) { $img = new Imager( new Canvas( $width, $height, array( 255, 255, 255 ) ), new Transparency( array( 255, 255, 255 ) ) ); $img = $img->transpColorToAlphaChannel(); $colors = $this->getHistogramData( $channel ); $min = min( $colors ); $max = max( $colors ); $ratio_h = $height / $max; $ratio_w = $width / 256; foreach( $colors as $k => $value ) { $x = round( $k * $ratio_w ); $img = $img->drawLine( $x, $height, $x, $height - ( $value * $ratio_h ), $color, $lineHeight ); } return $img; } /** * Change the transparency (alpha value) with the given value. * You can use negativ or positive value to increment or decrement the alpha value * * @param int $value * @return Imager $img */ public function transparency( $value = 0 ) { $img = $this->cloneObject(); $img->setTransparencyInfo( new Transparency( true ) ); imagealphablending( $img->imgres, false ); for( $x = 0; $x < $this->width; $x++ ) { for( $y = 0; $y < $this->height; $y++ ) { $pixel = imagecolorsforindex( $img->imgres, imagecolorat( $img->imgres, $x, $y ) ); $alpha = min( max( 0, $pixel[ 'alpha' ] + $value ), 127 ); $color = imagecolorallocatealpha( $img->imgres, $pixel[ 'red' ], $pixel[ 'green' ], $pixel[ 'blue' ], $alpha ); imagesetpixel( $img->imgres, $x, $y, $color ); } } return $img; } /** * Make Image from array values. The array format array[ x ][ y ] = value * or array[ x ][ y ] = array( 'red' => 0, 'green' => 0, 'blue' => 0, 'alpha' => 0 ) * * @param array $pixels * @return Imager */ public function createFromArray( array $pixels ) { $height = count( $pixels ); $width = count( $pixels[ 0 ] ); $img = new Imager( new Canvas( $width, $height ) ); $res = $img->getResource(); foreach( $pixels as $x => $row ) { foreach( $row as $y => $pixel ) { $r = $g = $b = 0; $color = null; if ( !is_array( $pixel ) ) { $r = $g = $b = $pixel; $color = imagecolorallocate( $res, $r, $g, $b ); } else { $color = imagecolorallocatealpha( $t, $pixel[ 'red' ], $pixel[ 'green' ], $pixel[ 'blue' ], $pixel[ 'alpha' ] ); } imagesetpixel( $res, $y, $x, $color ); } } return $img; } } ?>