<?php
/***********************************
*
* ImageMagick 图像处理
* 01-09-2006
* Dr.NP
zhanghao@megayou.com*
************************************
* 类名 : cls_graphic
* 方法列表 :
* ->crop () 切割图片中的部分
* ->border () 图像加边框
* ->extent () 重置图像大小,超出部分补黑
* ->resize () 重置图像大小,保持比例
* ->stretch () 拉伸
* ->middle_crop () 居中切割
* ->auto_crop () 自动切割
* ->fit_to_size () 自适应大小
* ->mask_image () 图片叠加
* ->imagetype () 源图类型
*/
define('IMAGEMAGICK_PATH', '/usr/local/bin/');
if (!class_exists ('cls_graphic')) {
class cls_graphic
{
var $classname = 'cls_graphic';
var $im_cmd_os = 'UNIX';
var $source_filename = '';
var $target_filename = '';
var $source_width = 0;
var $source_height = 0;
var $source_imagetype = '';
var $source_mimetype = '';
var $error_msg = '';
var $cmd_prefix = 'convert';
var $mogrify_prefix = 'mogrify';
function cls_graphic ($source_filename, $target_filename = '')
{
//构造函数,获得图像源文件名、设置目标文件名、获取图片尺寸、类型、MIME类型
if (!is_readable ($source_filename)) {
$this->error_msg = 'Cannot Open Source ImageFile';
return false;
}
$img_info_arr = @getimagesize ($source_filename);
if (!$img_info_arr) {
$this->error_msg = 'Cannot Fetch Image Type';
return false;
}
$this->source_width = $img_info_arr[0];
$this->source_height = $img_info_arr[1];
//image常量列表,与PHP4.3.0对应
switch ($img_info_arr[2]) {
case 1:
$this->source_imagetype = 'GIF';
$this->source_mimetype = 'image/gif';
break;
case 2:
$this->source_imagetype = 'JPG';
$this->source_mimetype = 'image/jpeg';
break;
case 3:
$this->source_imagetype = 'PNG';
$this->source_mimetype = 'image/png';
break;
case 4:
$this->source_imagetype = 'SWF';
$this->source_mimetype = 'application/x-shockwave-flash';
break;
case 5:
$this->source_imagetype = 'PSD';
$this->source_mimetype = 'image/psd';
break;
case 6:
$this->source_imagetype = 'BMP';
$this->source_mimetype = 'image/bmp';
break;
case 7:
$this->source_imagetype = 'TIFF';
$this->source_mimetype = 'image/tiff';
break;
case 8:
$this->source_imagetype = 'TIFF';
$this->source_mimetype = 'image/tiff';
break;
case 9:
$this->source_imagetype = 'JPC';
$this->source_mimetype = 'image/jpc';
break;
case 10:
$this->source_imagetype = 'JP2';
$this->source_mimetype = 'image/jp2';
break;
case 11:
$this->source_imagetype = 'JPX';
$this->source_mimetype = 'image/jpx';
break;
case 12:
$this->source_imagetype = 'JB2';
$this->source_mimetype = 'image/jb2';
break;
case 13:
$this->source_imagetype = 'SWC';
$this->source_mimetype = 'application/x-shockwave-flash';
break;
case 14:
$this->source_imagetype = 'IFF';
$this->source_mimetype = 'image/iff';
break;
case 15:
$this->source_imagetype = 'WBMP';
$this->source_mimetype = 'image/vnd.wap.wbmp';
break;
case 16:
$this->source_imagetype = 'XBM';
$this->source_mimetype = 'image/x-xbitmap';
break;
default:
$this->error_msg = 'Cannot Fetch the Source Image File's type';
return false;
}
$this->cmd_prefix = IMAGEMAGICK_PATH . 'convert';
$this->mogrify_prefix = IMAGEMAGICK_PATH . 'mogrify';
if (!is_executable ($this->cmd_prefix) || !is_executable ($this->mogrify_prefix)) {
$this->error_msg = 'ImageMagick Binary CommandLine Tool Access Denied';
return false;
}
$this->source_filename = $source_filename;
$this->target_filename = $target_filename;
}
function last_error ()
{
return $this->error_msg;
}
// 图像自定义大小,默认保持原图比例。对GIF图片采用-resize获得更好的调色板效果,静态图片用-thumbnail获得更好的性能
// 由于GIF89a使用的LZW压缩算法的版权问题,ImageMagick生成的GIF是不经过LZW压缩的,即使提供LZW参数也无效。
function resize ($new_width = 1, $new_height = 1)
{
if ($this->source_imagetype != 'GIF')
$cmd = $this->cmd_prefix . " -thumbnail {$new_width}x{$new_height} {$this->source_filename} {$this->target_filename}";
else
$cmd = $this->cmd_prefix . " -resize {$new_width}x{$new_height} {$this->source_filename} {$this->target_filename}";
$res = @exec ($cmd);
if (file_exists ($this->target_filename))
return true;
else
return false;
}
// 对图像完成切割,如果不指定相对坐标,ImageMagick默认将原始图像切割成若干个小图组成的图像序列
// $r_x和$r_y是切割部分的左上角相对于原图的左上角横纵坐标,可以指定负值
function crop ($new_width = 1, $new_height = 1, $r_x = 0, $r_y = 0)
{
$cmd = $this->cmd_prefix . " -crop {$new_width}x{$new_height}+{$r_x}+{$r_y} {$this->source_filename} {$this->target_filename}";
$res = @exec ($cmd);
if (file_exists ($this->target_filename))
return true;
else
return false;
}
// 对图像加边框,可以分别指定横向和纵向的边框宽度和边框颜色,可用于扩大图片尺寸并保持原始画面不变同时保持在新图的中央。
function border ($x_width, $y_width, $border_color = '#FFFFFF')
{
$cmd = $this->cmd_prefix . " -bordercolor '{$border_color}' -border {$x_width}x{$y_width} {$this->source_filename} {$this->target_filename}";
$res = @exec ($cmd);
if (file_exists ($this->target_filename))
return true;
else
return false;
}
// 重新调整图片大小,超出原图部分将在原图的右侧和底部添加黑色边框
function extent ($new_width = 1, $new_height = 1)
{
$cmd = $this->cmd_prefix . " -extent {$new_width}x{$new_height} {$this->source_filename} {$this->target_filename}";
$res = @exec ($cmd);
if (file_exists ($this->target_filename))
return true;
else
return false;
}
// 重设图片大小,但不保持图片纵横比,完全按照输入的参数拉伸
function stretch ($new_width = 1, $new_height = 1)
{
$cmd = $this->cmd_prefix . " -resize {$new_width}x{$new_height}! {$this->source_filename} {$this->target_filename}";
$res = @exec ($cmd);
if (file_exists ($this->target_filename))
return true;
else
return false;
}
// 居中切割,适合于做长宽比例过大的图片预览或创建合法比例头像等应用
function middle_crop ($new_width = 1, $new_height = 1)
{
/*
if ($new_width > $this->source_width)
$new_width = $this->source_width;
if ($new_height > $this->source_height)
$new_height = $this->source_height;
*/
$r_x = ceil (($this->source_width - $new_width) / 2);
$r_y = ceil (($this->source_height - $new_height) / 2);
return $this->crop ($new_width, $new_height, $r_x, $r_y);
}
// 自动切割,从图片中部取得符合裁切比例的一块并压缩到实际需要大小
function auto_crop ($new_width = 1, $new_height = 1)
{
$source_radio = $this->source_width / $this->source_height;
$target_radio = $new_width / $new_height;
if ($source_radio > $target_radio) {
// 原图宽高比例大于裁切宽高比,按高度切割。
$x = ceil ($this->source_height * ($source_radio - $target_radio) / 2);
$n_w = ceil ($this->source_height * $target_radio);
$cmd = $this->cmd_prefix . " -crop {$n_w}x{$this->source_height}+{$x}+0 {$this->source_filename} {$this->target_filename}";
@exec ($cmd);
}
elseif ($target_radio > $source_radio) {
// 原图宽高比例小于裁切宽高比,按宽度切割。
//$y = ceil (($source_radio * $this->source_height) / ($target_radio * 2));
$y = ceil (($this->source_height - $this->source_width / $target_radio) / 2);
$n_h = ceil ($this->source_width / $target_radio);
$cmd = $this->cmd_prefix . " -crop {$this->source_width}x{$n_h}+0+{$y} {$this->source_filename} {$this->target_filename}";
@exec ($cmd);
}
else
@copy ($this->source_filename, $this->target_filename);
$cmd = $this->mogrify_prefix . " -resize {$new_width}x{$new_height} {$this->target_filename}";
@exec ($cmd);
if (file_exists ($this->target_filename))
return true;
else
return false;
}
// 改变图片尺寸,并用指定颜色填充空白部分
function fit_to_size ($new_width = 1, $new_height = 1, $border_color = '#FFFFFF')
{
$x_width = 0;
$y_width = 0;
if ($new_width > $this->source_width)
$x_width = ceil (($new_width - $this->source_width) / 2);
if ($new_height > $this->source_height)
$y_width = ceil (($new_height - $this->source_height) / 2);
if ($x_width > 0 && $y_width > 0) {
if ($this->border ($x_width, $y_width, $border_color)) {
if (($this->source_width + $x_width * 2 > $new_width) || ($this->source_height + $y_width * 2 > $new_height)) {
$cmd = $this->mogrify_prefix . " -crop {$new_width}x{$new_height}+0+0 {$this->target_filename}";
@exec ($cmd);
}
}
else
return false;
}
else {
$this->resize ($new_width, $new_height);
$img_info_arr = @getimagesize ($this->target_filename);
$t_width = $img_info_arr[0];
$t_height = $img_info_arr[1];
$x_width = ceil (($new_width - $t_width) / 2);
$y_width = ceil (($new_height - $t_height) / 2);
if ($x_width > 0 || $y_width > 0) {
$cmd = $this->mogrify_prefix . " -bordercolor '{$border_color}' -border {$x_width}x{$y_width} {$this->target_filename}";
@exec ($cmd);
if (($t_width + $x_width * 2 > $new_width) || ($t_height + $y_width * 2 > $new_height)) {
$cmd = $this->mogrify_prefix . " -crop {$new_width}x{$new_height}+0+0 {$this->target_filename}";
@exec ($cmd);
}
}
}
if (file_exists ($this->target_filename))
return true;
else
return false;
}
//图片叠加
function mask_image ($img, $location = 4, $alpha = 255)
{
if (!is_readable ($img)) {
$this->error_msg = 'Mask Image File Could not be Opened!';
return false;
}
$mask_info = @getimagesize ($img);
if (!$mask_info || !is_array ($mask_info)) {
$this->error_msg = 'Mask is not a available IMAGE file.';
return false;
}
$mask_width = $mask_info[0];
$mask_height = $mask_info[1];
switch ($location) {
case 1 :
$x = 10;
$y = 10;
break;
case 2 :
$x = $this->source_width - 10 - $mask_width;
$y = 10;
break;
case 3 :
$x = 10;
$y = $this->source_height - 10 - $mask_height;
break;
case 4 :
$x = $this->source_width - 10 - $mask_width;
$y = $this->source_height - 10 - $mask_height;
break;
case 5 :
$x = ceil (($this->source_width - $mask_width) / 2);
$y = ceil (($this->source_height - $mask_height) / 2);
break;
default :
$this->error_msg = 'Wrong Location Method...';
return false;
}
$cmd = $this->cmd_prefix . " -channel Alpha -draw "image Over $x,$y 0,0 $img" {$this->source_filename} {$this->target_filename}";
@exec ($cmd);
if (file_exists ($this->target_filename))
return true;
else
return false;
}
}
}
?>