Last update: 2011-03-02 02:14:37
Et une petite classe pour traiter les images... ça prend pas mal de mémoire, mais ça permet aussi de faire très simplement plusieurs versions d'une image avec des successions de traitements sans recharger l'originale depuis le disque. Comme d'habitude, corrections à suivre dans le vrac.
/**
* Image manipulation class. Requires GD.
* Some methods from php.net contribution
*/
require_once ('md/Exception.php');
class md_Image_Exception extends md_Exception{}
class md_Image
{
private $originalFilePath;
private $originalMimeType;
private $originalX;
private $originalY;
private $originalBuffer;
private $tempBuffer;
/**
* Create new Image object.
*
* @param string Original file path.
* @param boolean Init temporary buffer.
*/
public function __construct($filePath, $initTempBuffer = true)
{
$imageInfos = getimagesize($filePath);
if(in_array($imageInfos['mime'], array('image/jpeg',
'image/png',
'image/gif')))
{
$this->originalFilePath = $filePath;
$this->originalMimeType = $imageInfos['mime'];
$this->originalX = $imageInfos[0];
$this->originalY = $imageInfos[1];
if($initTempBuffer)
{
$this->initTempBuffer();
}
}
else
{
throw new md_Image_Exception('invalid image format.');
}
}
/**
* Init temporary buffer, copying original buffer.
* Try to get original buffer from file.
*/
public function initTempBuffer()
{
if(empty($this->originalBuffer))
{
$this->getImageFromFile();
}
$this->tempBuffer = $this->originalBuffer;
}
/**
* Resize Image, keeping scale.
*
* @param integer New size.
* @param string Reference side to resize ("x" or "y"), "x" by default.
*/
public function resizeKeepScale($new_value,$side="x")
{
if((int)$new_value > 0)
{
if($side=="x")
{
$factor = $this->originalX / (int)$new_value;
$new_y = round($this->originalY / $factor);
$this->resize((int)$new_value,$new_y);
}
if($side=="y")
{
$factor = $this->originalY / (int)$new_value;
$new_x = round($this->originalX / $factor);
$this->resize($new_x,(int)$new_value);
}
}
else
{
throw new md_Image_Exception('Can\'t resize image to 0 pixel !');
}
}
/**
* Resize image so that it would fit in a square of given pixel size.
*
* @param integer Size of square.
*/
public function fitToSquare($size)
{
if($this->originalX > $this->originalY)
{
$this->resizeKeepScale((int)$size);
}
else
{
$this->resizeKeepScale((int)$size,"y");
}
}
public function fitInSquare($size, $color = array(255, 255, 255))
{
if(count($color) < 3)
{
throw new md_Image_Exception('wrong color');
}
$this->fitToSquare($size);
$dst= imagecreatetruecolor($size, $size);
$color = imagecolorallocate($dst, (int)$color[0], (int)$color[1], (int)$color[2]);
imagefill($dst, 0, 0, $color);
$bufferX = imagesx($this->tempBuffer);
$bufferY = imagesy($this->tempBuffer);
if($bufferX > $bufferY)
{
$moveY = $size / 2 - $bufferY / 2;
$moveX = 0;
}
else
{
$moveY = 0;
$moveX = $size / 2 - $bufferX / 2;
}
imagecopy($dst, $this->tempBuffer, $moveX, $moveY, 0, 0, $bufferX, $bufferY);
$this->tempBuffer = $dst;
}
/**
* Resize image to new x and new y.
*
* @param integer New size of x.
* @param integer New size of y.
*/
public function resize($new_x,$new_y)
{
if(!empty($this->tempBuffer))
{
$to = imagecreatetruecolor($new_x, $new_y);
$from = $this->tempBuffer;
imagecopyresampled($to, $from, 0, 0, 0, 0, $new_x, $new_y,
$this->originalX, $this->originalY);
$this->tempBuffer = $to;
}
else
{
throw new md_Image_Exception('Can\'t resize empty image buffer');
}
}
/**
* Save temporary buffer to file.
*
* @param string New file path.
* @param boolean Add extension, based on original file.
*/
public function toFile($newPath, $addExtension = true)
{
if(!empty($this->tempBuffer))
{
if($addExtension)
{
$newPath .= '.' . $this->getOriginalExtension();
}
switch($this->originalMimeType)
{
case 'image/jpeg':
imagejpeg($this->tempBuffer,$newPath);
break;
case 'image/png':
imagepng($this->tempBuffer,$newPath);
break;
case 'image/gif':
imagegif($this->tempBuffer,$newPath);
break;
}
}
else
{
throw new md_Image_Exception('Can not save empty buffer.');
}
}
/**
* Send buffer to browser
*/
public function toBrowser($die = true)
{
header('content-type: ' . $this->originalMimeType);
switch($this->originalMimeType)
{
case 'image/jpeg':
imagejpeg($this->tempBuffer);
break;
case 'image/png':
imagepng($this->tempBuffer);
break;
case 'image/gif':
imagegif($this->tempBuffer);
break;
}
if($die)
{
die;
}
}
/**
* Convert image to gray scale.
*/
public function grayScale()
{
if(!empty($this->tempBuffer))
{
imagefilter($this->tempBuffer, IMG_FILTER_GRAYSCALE);
}
}
/**
* Colorize image.
*
* @param integer Red value (0-255).
* @param integer Blue value (0-255).
* @param integer Green value (0-255).
* @param mixed Alpha channel.
*/
public function colorize($r, $b, $g, $alpha = null)
{
if(!empty($this->tempBuffer))
{
imagefilter($this->tempBuffer, IMG_FILTER_COLORIZE,
(int)$r,
(int)$b,
(int)$g,
$alpha);
}
}
/**
* Negates colors.
*/
public function negate()
{
if(!empty($this->tempBuffer))
{
imagefilter($this->tempBuffer, IMG_FILTER_NEGATE);
}
}
/**
* Adjust brightness.
*
* @param integer brightness value
*/
public function brightness($val)
{
if(!empty($this->tempBuffer))
{
imagefilter($this->tempBuffer, IMG_FILTER_BRIGHTNESS, (int)$val);
}
}
/**
* Adjust contrast.
*
* @param integer contrast value
*/
public function contrast($val)
{
if(!empty($this->tempBuffer))
{
imagefilter($this->tempBuffer, IMG_FILTER_CONTRAST, (int)$val);
}
}
/**
* Edge effect
*/
public function edgeDetect()
{
if(!empty($this->tempBuffer))
{
imagefilter($this->tempBuffer, IMG_FILTER_EDGEDETECT);
}
}
/**
* Emboss effect
*/
public function emboss()
{
if(!empty($this->tempBuffer))
{
imagefilter($this->tempBuffer, IMG_FILTER_EMBOSS);
}
}
/**
* Gaussian blur
*/
public function gaussianBlur()
{
if(!empty($this->tempBuffer))
{
imagefilter($this->tempBuffer, IMG_FILTER_GAUSSIAN_BLUR);
}
}
/**
* Selective blur
*/
public function selectiveBlur()
{
if(!empty($this->tempBuffer))
{
imagefilter($this->tempBuffer, IMG_FILTER_SELECTIVE_BLUR);
}
}
/**
* Mean removal
*/
public function meanRemoval()
{
if(!empty($this->tempBuffer))
{
imagefilter($this->tempBuffer, IMG_FILTER_MEAN_REMOVAL);
}
}
/**
* Smooth effect
*/
public function smooth($val)
{
if(!empty($this->tempBuffer))
{
imagefilter($this->tempBuffer, IMG_FILTER_SMOOTH, (int)$val);
}
}
/**
* Create "Apple-like" reflection effect
*/
public function reflection()
{
$src_img = $this->tempBuffer;
$src_height = imagesy($src_img);
$src_width = imagesx($src_img);
$dest_height = $src_height + ($src_height / 2);
$dest_width = $src_width;
$reflected = imagecreatetruecolor($dest_width, $dest_height);
imagealphablending($reflected, false);
imagesavealpha($reflected, true);
imagecopy($reflected, $src_img, 0, 0, 0, 0, $src_width, $src_height);
$reflection_height = $src_height / 2;
$alpha_step = 80 / $reflection_height;
for ($y = 1; $y <= $reflection_height; $y++)
{
for ($x = 0; $x < $dest_width; $x++)
{
// copy pixel from x / $src_height - y to x / $src_height + y
$rgba = imagecolorat($src_img, $x, $src_height - $y);
$alpha = ($rgba & 0x7F000000) >> 24;
$alpha = max($alpha, 47 + ($y * $alpha_step));
$rgba = imagecolorsforindex($src_img, $rgba);
$rgba = imagecolorallocatealpha($reflected, $rgba['red'], $rgba['green'], $rgba['blue'], $alpha);
imagesetpixel($reflected, $x, $src_height + $y - 1, $rgba);
}
}
$this->tempBuffer = $reflected;
}
public function logo($src_image, $src_w, $src_h, $position='random')
{
$dst_w = imagesx($this->tempBuffer);
$dst_h = imagesy($this->tempBuffer);
imagealphablending($this->tempBuffer,true);
imagealphablending($src_image,true);
if ($position == 'random')
{
$position = rand(1,8);
}
switch ($position)
{
case 'top-right':
case 'right-top':
case 1:
imagecopy($this->tempBuffer, $src_image, ($dst_w-$src_w), 0, 0, 0, $src_w, $src_h);
break;
case 'top-left':
case 'left-top':
case 2:
imagecopy($this->tempBuffer, $src_image, 0, 0, 0, 0, $src_w, $src_h);
break;
case 'bottom-right':
case 'right-bottom':
case 3:
imagecopy($this->tempBuffer, $src_image, ($dst_w-$src_w), ($dst_h-$src_h), 0, 0, $src_w, $src_h);
break;
case 'bottom-left':
case 'left-bottom':
case 4:
imagecopy($this->tempBuffer, $src_image, 0 , ($dst_h-$src_h), 0, 0, $src_w, $src_h);
break;
case 'center':
case 5:
imagecopy($this->tempBuffer, $src_image, (($dst_w/2)-($src_w/2)), (($dst_h/2)-($src_h/2)), 0, 0, $src_w, $src_h);
break;
case 'top':
case 6:
imagecopy($this->tempBuffer, $src_image, (($dst_w/2)-($src_w/2)), 0, 0, 0, $src_w, $src_h);
break;
case 'bottom':
case 7:
imagecopy($this->tempBuffer, $src_image, (($dst_w/2)-($src_w/2)), ($dst_h-$src_h), 0, 0, $src_w, $src_h);
break;
case 'left':
case 8:
imagecopy($this->tempBuffer, $src_image, 0, (($dst_h/2)-($src_h/2)), 0, 0, $src_w, $src_h);
break;
case 'right':
case 9:
imagecopy($this->tempBuffer, $src_image, ($dst_w-$src_w), (($dst_h/2)-($src_h/2)), 0, 0, $src_w, $src_h);
break;
}
}
private function getImageFromFile()
{
switch($this->originalMimeType)
{
case 'image/jpeg':
$this->originalBuffer = imagecreatefromjpeg($this->originalFilePath);
break;
case 'image/png':
$this->originalBuffer = imagecreatefrompng($this->originalFilePath);
break;
case 'image/gif':
$this->originalBuffer = imagecreatefromgif($this->originalFilePath);
break;
}
}
private function getOriginalExtension()
{
switch($this->originalMimeType)
{
case 'image/jpeg':
return 'jpg';
break;
case 'image/png':
return 'png';
break;
case 'image/gif':
return 'gif';
break;
default:
return '';
break;
}
}
}
Suggestion d'utilisation:
require('md/Image.php');
$i = new md_Image('image.png');
$i->fitToSquare(200);
$i->toBrowser();