浅谈php扩展imagick

前端之家收集整理的这篇文章主要介绍了浅谈php扩展imagick前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

PHP建图通常都用GD库,因为是内置的不需要在服务器上额外安装插件,所以用起来比较省心,但是如果你的程序主要的功能就是处理图像,那麼就不建议用GD了,因为GD不但低效能而且能力也比较弱,佔用的系统资源也颇多,另外GD的creatfrom也有bug,而imagick却是一个很好的替代品,为此最近把我的一个项目由GD改成了imagick,但是改完之后出现了一些状况在此分享给大家.

首先说一下我这边出现的状况:

状况一:需要重写图像操作class

状况二:imagick多线程时会导致cpu使用率暴增到100%

在此顺便提一下imagick在centos6.4的安装方法:

1、安装ImageMagick

代码如下:
404_15@wget http://soft.vpser.net/web/imagemagick/ImageMagick-6.7.1-2.tar.gz@H_404_15@tar zxvf ImageMagick-6.7.1-2.tar.gz@H_404_15@cd ImageMagick-6.7.1-2/@H_404_15@./configure --prefix=/usr/local/imagemagick --disable-openmp@H_404_15@make && make install@H_404_15@ldconfig@H_404_15@

测试ImageMagick是否可以正常运行:

代码如下:
404_15@/usr/local/imagemagick/bin/convert -version@H_404_15@

2、安装PHP扩展:imagick

代码如下:
404_15@wget http://pecl.PHP.net/get/imagick-3.0.1.tgz@H_404_15@tar zxvf imagick-3.0.1.tgz@H_404_15@cd imagick-3.0.1/@H_404_15@/usr/local/PHP/bin/PHPize@H_404_15@./configure --with-PHP-config=/usr/local/PHP/bin/PHP-config --with-imagick=/usr/local/imagemagick@H_404_15@make && make install@H_404_15@ldconfig@H_404_15@vi /usr/local/PHP/etc/PHP.ini@H_404_15@添加:extension = "imagick.so"@H_404_15@

重启lnmp@H_404_15@

代码如下:
404_15@/root/lnmp reload@H_404_15@

接下来我们针对上述两个状况分别提出解决办法:

状况一的解决办法如下:

代码如下:
404_15@/**@H_404_15@ Imagick图像处理类@H_404_15@ 用法:@H_404_15@ //引入Imagick物件@H_404_15@ if(!defined('CLASS_IMAGICK')){require(Inc.'class_imagick.PHP');}@H_404_15@ $Imagick=new class_imagick();@H_404_15@ $Imagick->open('a.gif');@H_404_15@ $Imagick->resize_to(100,100,'scale_fill');@H_404_15@ $Imagick->add_text('1024i.com',10,20);@H_404_15@ $Imagick->add_watermark('1024i.gif',50);@H_404_15@ $Imagick->save_to('x.gif');@H_404_15@ unset($Imagick);@H_404_15@/**/@H_404_15@define('CLASS_IMAGICK',TRUE);@H_404_15@class class_imagick{@H_404_15@ private $image=null;@H_404_15@ private $type=null;@H_404_15@ // 构造@H_404_15@ public function __construct(){}@H_404_15@ // 析构@H_404_15@ public function __destruct(){@H_404_15@ if($this->image!==null){$this->image->destroy();}@H_404_15@ }@H_404_15@ // 载入图像@H_404_15@ public function open($path){@H_404_15@ if(!file_exists($path)){@H_404_15@ $this->image=null;@H_404_15@ return ;@H_404_15@ }@H_404_15@ $this->image=new Imagick($path);@H_404_15@ if($this->image){@H_404_15@ $this->type=strtolower($this->image->getImageFormat());@H_404_15@ }@H_404_15@ $this->image->stripImage();@H_404_15@ return $this->image;@H_404_15@ }@H_404_15@ /**@H_404_15@ 图像裁切@H_404_15@ /**/@H_404_15@ public function crop($x=0,$y=0,$width=null,$height=null){@H_404_15@ if($width==null) $width=$this->image->getImageWidth()-$x;@H_404_15@ if($height==null) $height=$this->image->getImageHeight()-$y;@H_404_15@ if($width<=0 || $height<=0) return;@H_404_15@ if($this->type=='gif'){@H_404_15@ $image=$this->image;@H_404_15@ $canvas=new Imagick();@H_404_15@ $images=$image->coalesceImages();@H_404_15@ foreach($images as $frame){@H_404_15@ $img=new Imagick();@H_404_15@ $img->readImageBlob($frame);@H_404_15@ $img->cropImage($width,$height,$x,$y);@H_404_15@ $canvas->addImage($img);@H_404_15@ $canvas->setImageDelay($img->getImageDelay());@H_404_15@ $canvas->setImagePage($width,0);@H_404_15@ }@H_404_15@ $image->destroy();@H_404_15@ $this->image=$canvas;@H_404_15@ }else{@H_404_15@ $this->image->cropImage($width,$y);@H_404_15@ }@H_404_15@ }@H_404_15@ /**@H_404_15@ 更改图像大小@H_404_15@ 参数:@H_404_15@ $width:新的宽度@H_404_15@ $height:新的高度@H_404_15@ $fit: 适应大小@H_404_15@ 'force': 把图像强制改为$width X $height@H_404_15@ 'scale': 按比例在$width X $height内缩放图片,结果不完全等於$width X $height@H_404_15@ 'scale_fill':按比例在$width X $height内缩放图片,没有像素的地方填充顏色$fill_color=array(255,255,255)(红,绿,蓝,透明度[0不透明-127全透明])@H_404_15@ 其他:智能模式,缩放图片并从正中裁切$width X $height的大小@H_404_15@ 注意:@H_404_15@ $fit='force','scale','scale_fill'时输出完整图像@H_404_15@ $fit=图像方位时输出指定位置部份的图像@H_404_15@ 字母与图像的对应关系如下:@H_404_15@ north_west north north_east@H_404_15@ west center east@H_404_15@ south_west south south_east@H_404_15@ /**/@H_404_15@ public function resize_to($width=100,$height=100,$fit='center',$fill_color=array(255,0)){@H_404_15@ switch($fit){@H_404_15@ case 'force':@H_404_15@ if($this->type=='gif'){@H_404_15@ $image=$this->image;@H_404_15@ $canvas=new Imagick();@H_404_15@ $images=$image->coalesceImages();@H_404_15@ foreach($images as $frame){@H_404_15@ $img=new Imagick();@H_404_15@ $img->readImageBlob($frame);@H_404_15@ $img->thumbnailImage($width,false);@H_404_15@ $canvas->addImage($img);@H_404_15@ $canvas->setImageDelay($img->getImageDelay());@H_404_15@ }@H_404_15@ $image->destroy();@H_404_15@ $this->image=$canvas;@H_404_15@ }else{@H_404_15@ $this->image->thumbnailImage($width,false);@H_404_15@ }@H_404_15@ break;@H_404_15@ case 'scale':@H_404_15@ if($this->type=='gif'){@H_404_15@ $image=$this->image;@H_404_15@ $images=$image->coalesceImages();@H_404_15@ $canvas=new Imagick();@H_404_15@ foreach($images as $frame){@H_404_15@ $img=new Imagick();@H_404_15@ $img->readImageBlob($frame);@H_404_15@ $img->thumbnailImage($width,true);@H_404_15@ $canvas->addImage($img);@H_404_15@ $canvas->setImageDelay($img->getImageDelay());@H_404_15@ }@H_404_15@ $image->destroy();@H_404_15@ $this->image=$canvas;@H_404_15@ }else{@H_404_15@ $this->image->thumbnailImage($width,true);@H_404_15@ }@H_404_15@ break;@H_404_15@ case 'scale_fill':@H_404_15@ $size=$this->image->getImagePage();@H_404_15@ $src_width=$size['width'];@H_404_15@ $src_height=$size['height'];@H_404_15@ $x=0;@H_404_15@ $y=0;@H_404_15@ $dst_width=$width;@H_404_15@ $dst_height=$height;@H_404_15@ if($src_width*$height > $src_height*$width){@H_404_15@ $dst_height=intval($width*$src_height/$src_width);@H_404_15@ $y=intval(($height-$dst_height)/2);@H_404_15@ }else{@H_404_15@ $dst_width=intval($height*$src_width/$src_height);@H_404_15@ $x=intval(($width-$dst_width)/2);@H_404_15@ }@H_404_15@ $image=$this->image;@H_404_15@ $canvas=new Imagick();@H_404_15@ $color='rgba('.$fill_color[0].','.$fill_color[1].','.$fill_color[2].','.$fill_color[3].')';@H_404_15@ if($this->type=='gif'){@H_404_15@ $images=$image->coalesceImages();@H_404_15@ foreach($images as $frame){@H_404_15@ $frame->thumbnailImage($width,true);@H_404_15@ $draw=new ImagickDraw();@H_404_15@ $draw->composite($frame->getImageCompose(),$y,$dst_width,$dst_height,$frame);@H_404_15@ $img=new Imagick();@H_404_15@ $img->newImage($width,$color,'gif');@H_404_15@ $img->drawImage($draw);@H_404_15@ $canvas->addImage($img);@H_404_15@ $canvas->setImageDelay($img->getImageDelay());@H_404_15@ $canvas->setImagePage($width,0);@H_404_15@ }@H_404_15@ }else{@H_404_15@ $image->thumbnailImage($width,true);@H_404_15@ $draw=new ImagickDraw();@H_404_15@ $draw->composite($image->getImageCompose(),$image);@H_404_15@ $canvas->newImage($width,$this->get_type());@H_404_15@ $canvas->drawImage($draw);@H_404_15@ $canvas->setImagePage($width,0);@H_404_15@ }@H_404_15@ $image->destroy();@H_404_15@ $this->image=$canvas;@H_404_15@ break;@H_404_15@ default:@H_404_15@ $size=$this->image->getImagePage();@H_404_15@ $src_width=$size['width'];@H_404_15@ $src_height=$size['height'];@H_404_15@ $crop_x=0;@H_404_15@ $crop_y=0;@H_404_15@ $crop_w=$src_width;@H_404_15@ $crop_h=$src_height;@H_404_15@ if($src_width*$height > $src_height*$width){@H_404_15@ $crop_w=intval($src_height*$width/$height);@H_404_15@ }else{@H_404_15@ $crop_h=intval($src_width*$height/$width);@H_404_15@ }@H_404_15@ switch($fit){@H_404_15@ case 'north_west':@H_404_15@ $crop_x=0;@H_404_15@ $crop_y=0;@H_404_15@ break;@H_404_15@ case 'north':@H_404_15@ $crop_x=intval(($src_width-$crop_w)/2);@H_404_15@ $crop_y=0;@H_404_15@ break;@H_404_15@ case 'north_east':@H_404_15@ $crop_x=$src_width-$crop_w;@H_404_15@ $crop_y=0;@H_404_15@ break;@H_404_15@ case 'west':@H_404_15@ $crop_x=0;@H_404_15@ $crop_y=intval(($src_height-$crop_h)/2);@H_404_15@ break;@H_404_15@ case 'center':@H_404_15@ $crop_x=intval(($src_width-$crop_w)/2);@H_404_15@ $crop_y=intval(($src_height-$crop_h)/2);@H_404_15@ break;@H_404_15@ case 'east':@H_404_15@ $crop_x=$src_width-$crop_w;@H_404_15@ $crop_y=intval(($src_height-$crop_h)/2);@H_404_15@ break;@H_404_15@ case 'south_west':@H_404_15@ $crop_x=0;@H_404_15@ $crop_y=$src_height-$crop_h;@H_404_15@ break;@H_404_15@ case 'south':@H_404_15@ $crop_x=intval(($src_width-$crop_w)/2);@H_404_15@ $crop_y=$src_height-$crop_h;@H_404_15@ break;@H_404_15@ case 'south_east':@H_404_15@ $crop_x=$src_width-$crop_w;@H_404_15@ $crop_y=$src_height-$crop_h;@H_404_15@ break;@H_404_15@ default:@H_404_15@ $crop_x=intval(($src_width-$crop_w)/2);@H_404_15@ $crop_y=intval(($src_height-$crop_h)/2);@H_404_15@ }@H_404_15@ $image=$this->image;@H_404_15@ $canvas=new Imagick();@H_404_15@ if($this->type=='gif'){@H_404_15@ $images=$image->coalesceImages();@H_404_15@ foreach($images as $frame){@H_404_15@ $img=new Imagick();@H_404_15@ $img->readImageBlob($frame);@H_404_15@ $img->cropImage($crop_w,$crop_h,$crop_x,$crop_y);@H_404_15@ $img->thumbnailImage($width,true);@H_404_15@ $canvas->addImage($img);@H_404_15@ $canvas->setImageDelay($img->getImageDelay());@H_404_15@ $canvas->setImagePage($width,0);@H_404_15@ }@H_404_15@ }else{@H_404_15@ $image->cropImage($crop_w,$crop_y);@H_404_15@ $image->thumbnailImage($width,true);@H_404_15@ $canvas->addImage($image);@H_404_15@ $canvas->setImagePage($width,0);@H_404_15@ }@H_404_15@ $image->destroy();@H_404_15@ $this->image=$canvas;@H_404_15@ }@H_404_15@ }@H_404_15@ /**@H_404_15@ 添加图片水印@H_404_15@ 参数:@H_404_15@ $path:水印图片(包含完整路径)@H_404_15@ $x,$y:水印座标@H_404_15@ /**/@H_404_15@ public function add_watermark($path,$x=0,$y=0){@H_404_15@ $watermark=new Imagick($path);@H_404_15@ $draw=new ImagickDraw();@H_404_15@ $draw->composite($watermark->getImageCompose(),$watermark->getImageWidth(),$watermark->getimageheight(),$watermark);@H_404_15@ if($this->type=='gif'){@H_404_15@ $image=$this->image;@H_404_15@ $canvas=new Imagick();@H_404_15@ $images=$image->coalesceImages();@H_404_15@ foreach($image as $frame){@H_404_15@ $img=new Imagick();@H_404_15@ $img->readImageBlob($frame);@H_404_15@ $img->drawImage($draw);@H_404_15@ $canvas->addImage($img);@H_404_15@ $canvas->setImageDelay($img->getImageDelay());@H_404_15@ }@H_404_15@ $image->destroy();@H_404_15@ $this->image=$canvas;@H_404_15@ }else{@H_404_15@ $this->image->drawImage($draw);@H_404_15@ }@H_404_15@ }@H_404_15@ /**@H_404_15@ 添加文字水印@H_404_15@ 参数:@H_404_15@ $text:水印文字@H_404_15@ $x,$y:水印座标@H_404_15@ /**/@H_404_15@ public function add_text($text,$angle=0,$style=array()){@H_404_15@ $draw=new ImagickDraw();@H_404_15@ if(isset($style['font'])) $draw->setFont($style['font']);@H_404_15@ if(isset($style['font_size'])) $draw->setFontSize($style['font_size']);@H_404_15@ if(isset($style['fill_color'])) $draw->setFillColor($style['fill_color']);@H_404_15@ if(isset($style['under_color'])) $draw->setTextUnderColor($style['under_color']);@H_404_15@ if($this->type=='gif'){@H_404_15@ foreach($this->image as $frame){@H_404_15@ $frame->annotateImage($draw,$angle,$text);@H_404_15@ }@H_404_15@ }else{@H_404_15@ $this->image->annotateImage($draw,$text);@H_404_15@ }@H_404_15@ }@H_404_15@ /**@H_404_15@ 图片存档@H_404_15@ 参数:@H_404_15@ $path:存档的位置和新的档案名@H_404_15@ /**/@H_404_15@ public function save_to($path){@H_404_15@ $this->image->stripImage();@H_404_15@ switch($this->type){@H_404_15@ case 'gif':@H_404_15@ $this->image->writeImages($path,true);@H_404_15@ return ;@H_404_15@ case 'jpg':@H_404_15@ case 'jpeg':@H_404_15@ $this->image->setImageCompressionQuality($_ENV['ImgQ']);@H_404_15@ $this->image->writeImage($path);@H_404_15@ return ;@H_404_15@ case 'png':@H_404_15@ $flag = $this->image->getImageAlphaChannel();@H_404_15@ // 如果png背景不透明则压缩@H_404_15@ if(imagick::ALPHACHANNEL_UNDEFINED == $flag or imagick::ALPHACHANNEL_DEACTIVATE == $flag){@H_404_15@ $this->image->setImageType(imagick::IMGTYPE_PALETTE);@H_404_15@ $this->image->writeImage($path);@H_404_15@ }else{@H_404_15@ $this->image->writeImage($path);@H_404_15@ }unset($flag);@H_404_15@ return ;@H_404_15@ default:@H_404_15@ $this->image->writeImage($path);@H_404_15@ return ;@H_404_15@ }@H_404_15@ }@H_404_15@ // 直接输出图像到萤幕@H_404_15@ public function output($header=true){@H_404_15@ if($header) header('Content-type: '.$this->type);@H_404_15@ echo $this->image->getImagesBlob();@H_404_15@ }@H_404_15@ /**@H_404_15@ 建立缩小图@H_404_15@ $fit为真时,将保持比例并在$width X $height内產生缩小图@H_404_15@ /**/@H_404_15@ public function thumbnail($width=100,$fit=true){$this->image->thumbnailImage($width,$fit);}@H_404_15@ /**@H_404_15@ 给图像添加边框@H_404_15@ $width: 左右边框宽度@H_404_15@ $height: 上下边框宽度@H_404_15@ $color: 顏色@H_404_15@ /**/@H_404_15@ public function border($width,$color='rgb(220,220,220)'){@H_404_15@ $color=new ImagickPixel();@H_404_15@ $color->setColor($color);@H_404_15@ $this->image->borderImage($color,$width,$height);@H_404_15@ }@H_404_15@ //取得图像宽度@H_404_15@ public function get_width(){$size=$this->image->getImagePage();return $size['width'];}@H_404_15@ //取得图像高度@H_404_15@ public function get_height(){$size=$this->image->getImagePage();return $size['height'];}@H_404_15@ // 设置图像类型@H_404_15@ public function set_type($type='png'){$this->type=$type;$this->image->setImageFormat($type);}@H_404_15@ // 取得图像类型@H_404_15@ public function get_type(){return $this->type;}@H_404_15@ public function blur($radius,$sigma){$this->image->blurImage($radius,$sigma);} // 模糊@H_404_15@ public function gaussian_blur($radius,$sigma){$this->image->gaussianBlurImage($radius,$sigma);} // 高斯模糊@H_404_15@ public function motion_blur($radius,$sigma,$angle){$this->image->motionBlurImage($radius,$angle);} // 运动模糊@H_404_15@ public function radial_blur($radius){$this->image->radialBlurImage($radius);} // 径向模糊@H_404_15@ public function add_noise($type=null){$this->image->addNoiseImage($type==null?imagick::NOISE_IMPULSE:$type);} // 添加噪点@H_404_15@ public function level($black_point,$gamma,$white_point){$this->image->levelImage($black_point,$white_point);} // 调整色阶@H_404_15@ public function modulate($brightness,$saturation,$hue){$this->image->modulateImage($brightness,$hue);} // 调整亮度,饱和度,色调@H_404_15@ public function charcoal($radius,$sigma){$this->image->charcoalImage($radius,$sigma);} // 素描效果@H_404_15@ public function oil_paint($radius){$this->image->oilPaintImage($radius);} // 油画效果@H_404_15@ public function flop(){$this->image->flopImage();} // 水平翻转@H_404_15@ public function flip(){$this->image->flipImage();} // 垂直翻转@H_404_15@}@H_404_15@

状况二的解决办法如下:

首先用/usr/local/imagemagick/bin/convert -version指令查看一下输出内容是否已经开啟了多线程,Features:的值为空说明是单线程,如果Features:的值是openMP说明是多线程.imagick的多线程模式有一个bug,他会导致多核心的cpu使用率瞬间飆升到100所以一定要使用它的单线程模式才行.

代码如下:
404_15@Version: ImageMagick 6.7.1-2 2014-05-29 Q16 http://www.imagemagick.org@H_404_15@Copyright: Copyright (C) 1999-2011 ImageMagick Studio LLC@H_404_15@Features: @H_404_15@

上边是我配置正确时显示的结果,如果没有配置正确会显示下边的结果

代码如下:
404_15@Version: ImageMagick 6.7.1-2 2014-05-29 Q16 http://www.imagemagick.org@H_404_15@Copyright: Copyright (C) 1999-2011 ImageMagick Studio LLC@H_404_15@Features: openMP@H_404_15@

第一种结果是单线程模式,第二种结果是多线程模式,因为imagick的多线程模式有bug,所以如果您刚开始是用多线程模式安装的imagick那就必须要yum remove imagemagick将其卸载掉重新安装才行.

经过重写class,重装imagick之后一切正常,而且处理图像的效能比之以前有了大幅提升

@H_404_15@

猜你在找的PHP相关文章