源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

浅谈php扩展imagick

  • 时间:2020-10-03 01:15 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:浅谈php扩展imagick
PHP建图通常都用GD库,因为是内置的不需要在服务器上额外安装插件,所以用起来比较省心,但是如果你的程序主要的功能就是处理图像,那麼就不建议用GD了,因为GD不但低效能而且能力也比较弱,佔用的系统资源也颇多,另外GD的creatfrom也有bug,而imagick却是一个很好的替代品,为此最近把我的一个项目由GD改成了imagick,但是改完之后出现了一些状况在此分享给大家. 首先说一下我这边出现的状况: 状况一:需要重写图像操作class 状况二:imagick多线程时会导致cpu使用率暴增到100% 在此顺便提一下imagick在centos6.4的安装方法: 1、安装ImageMagick
[u]复制代码[/u] 代码如下:
wget http://soft.vpser.net/web/imagemagick/ImageMagick-6.7.1-2.tar.gz tar zxvf ImageMagick-6.7.1-2.tar.gz cd ImageMagick-6.7.1-2/ ./configure --prefix=/usr/local/imagemagick --disable-openmp make && make install ldconfig
测试ImageMagick是否可以正常运行:
[u]复制代码[/u] 代码如下:
/usr/local/imagemagick/bin/convert -version
2、安装PHP扩展:imagick
[u]复制代码[/u] 代码如下:
wget http://pecl.php.net/get/imagick-3.0.1.tgz tar zxvf imagick-3.0.1.tgz cd imagick-3.0.1/ /usr/local/php/bin/phpize ./configure --with-php-config=/usr/local/php/bin/php-config --with-imagick=/usr/local/imagemagick make && make install ldconfig vi /usr/local/php/etc/php.ini 添加:extension = "imagick.so"
重启lnmp
[u]复制代码[/u] 代码如下:
/root/lnmp reload
接下来我们针对上述两个状况分别提出解决办法: 状况一的解决办法如下:
[u]复制代码[/u] 代码如下:
/**     Imagick图像处理类     用法:         //引入Imagick物件         if(!defined('CLASS_IMAGICK')){require(Inc.'class_imagick.php');}         $Imagick=new class_imagick();         $Imagick->open('a.gif');         $Imagick->resize_to(100,100,'scale_fill');         $Imagick->add_text('1024i.com',10,20);         $Imagick->add_watermark('1024i.gif',10,50);         $Imagick->save_to('x.gif');         unset($Imagick); /**/ define('CLASS_IMAGICK',TRUE); class class_imagick{     private $image=null;     private $type=null;     // 构造     public function __construct(){}     // 析构     public function __destruct(){         if($this->image!==null){$this->image->destroy();}     }     // 载入图像     public function open($path){         if(!file_exists($path)){             $this->image=null;             return ;         }         $this->image=new Imagick($path);         if($this->image){             $this->type=strtolower($this->image->getImageFormat());         }         $this->image->stripImage();         return $this->image;     }     /**         图像裁切     /**/     public function crop($x=0,$y=0,$width=null,$height=null){         if($width==null) $width=$this->image->getImageWidth()-$x;         if($height==null) $height=$this->image->getImageHeight()-$y;         if($width<=0 || $height<=0) return;         if($this->type=='gif'){             $image=$this->image;             $canvas=new Imagick();             $images=$image->coalesceImages();             foreach($images as $frame){                 $img=new Imagick();                 $img->readImageBlob($frame);                 $img->cropImage($width,$height,$x,$y);                 $canvas->addImage($img);                 $canvas->setImageDelay($img->getImageDelay());                 $canvas->setImagePage($width,$height,0,0);             }             $image->destroy();             $this->image=$canvas;         }else{             $this->image->cropImage($width,$height,$x,$y);         }     }     /**         更改图像大小         参数:             $width:新的宽度             $height:新的高度             $fit: 适应大小                 'force': 把图像强制改为$width X $height                 'scale': 按比例在$width X $height内缩放图片,结果不完全等於$width X $height                 'scale_fill':按比例在$width X $height内缩放图片,没有像素的地方填充顏色$fill_color=array(255,255,255)(红,绿,蓝,透明度[0不透明-127全透明])                 其他:智能模式,缩放图片并从正中裁切$width X $height的大小         注意:             $fit='force','scale','scale_fill'时输出完整图像             $fit=图像方位时输出指定位置部份的图像         字母与图像的对应关系如下:             north_west   north   north_east             west         center        east             south_west   south   south_east     /**/     public function resize_to($width=100,$height=100,$fit='center',$fill_color=array(255,255,255,0)){         switch($fit){         case 'force':             if($this->type=='gif'){                 $image=$this->image;                 $canvas=new Imagick();                 $images=$image->coalesceImages();                 foreach($images as $frame){                     $img=new Imagick();                     $img->readImageBlob($frame);                     $img->thumbnailImage($width,$height,false);                     $canvas->addImage($img);                     $canvas->setImageDelay($img->getImageDelay());                 }                 $image->destroy();                 $this->image=$canvas;             }else{                 $this->image->thumbnailImage($width,$height,false);             }             break;         case 'scale':             if($this->type=='gif'){                 $image=$this->image;                 $images=$image->coalesceImages();                 $canvas=new Imagick();                 foreach($images as $frame){                     $img=new Imagick();                     $img->readImageBlob($frame);                     $img->thumbnailImage($width,$height,true);                     $canvas->addImage($img);                     $canvas->setImageDelay($img->getImageDelay());                 }                 $image->destroy();                 $this->image=$canvas;             }else{                 $this->image->thumbnailImage($width,$height,true);             }             break;         case 'scale_fill':             $size=$this->image->getImagePage();             $src_width=$size['width'];             $src_height=$size['height'];             $x=0;             $y=0;             $dst_width=$width;             $dst_height=$height;             if($src_width*$height > $src_height*$width){                 $dst_height=intval($width*$src_height/$src_width);                 $y=intval(($height-$dst_height)/2);             }else{                 $dst_width=intval($height*$src_width/$src_height);                 $x=intval(($width-$dst_width)/2);             }             $image=$this->image;             $canvas=new Imagick();             $color='rgba('.$fill_color[0].','.$fill_color[1].','.$fill_color[2].','.$fill_color[3].')';             if($this->type=='gif'){                 $images=$image->coalesceImages();                 foreach($images as $frame){                     $frame->thumbnailImage($width,$height,true);                     $draw=new ImagickDraw();                     $draw->composite($frame->getImageCompose(),$x,$y,$dst_width,$dst_height,$frame);                     $img=new Imagick();                     $img->newImage($width,$height,$color,'gif');                     $img->drawImage($draw);                     $canvas->addImage($img);                     $canvas->setImageDelay($img->getImageDelay());                     $canvas->setImagePage($width,$height,0,0);                 }             }else{                 $image->thumbnailImage($width,$height,true);                 $draw=new ImagickDraw();                 $draw->composite($image->getImageCompose(),$x,$y,$dst_width,$dst_height,$image);                 $canvas->newImage($width,$height,$color,$this->get_type());                 $canvas->drawImage($draw);                 $canvas->setImagePage($width,$height,0,0);             }             $image->destroy();             $this->image=$canvas;             break;         default:             $size=$this->image->getImagePage();             $src_width=$size['width'];             $src_height=$size['height'];             $crop_x=0;             $crop_y=0;             $crop_w=$src_width;             $crop_h=$src_height;             if($src_width*$height > $src_height*$width){                 $crop_w=intval($src_height*$width/$height);             }else{                 $crop_h=intval($src_width*$height/$width);             }             switch($fit){                 case 'north_west':                     $crop_x=0;                     $crop_y=0;                     break;                 case 'north':                     $crop_x=intval(($src_width-$crop_w)/2);                     $crop_y=0;                     break;                 case 'north_east':                     $crop_x=$src_width-$crop_w;                     $crop_y=0;                     break;                 case 'west':                     $crop_x=0;                     $crop_y=intval(($src_height-$crop_h)/2);                     break;                 case 'center':                     $crop_x=intval(($src_width-$crop_w)/2);                     $crop_y=intval(($src_height-$crop_h)/2);                     break;                 case 'east':                     $crop_x=$src_width-$crop_w;                     $crop_y=intval(($src_height-$crop_h)/2);                     break;                 case 'south_west':                     $crop_x=0;                     $crop_y=$src_height-$crop_h;                     break;                 case 'south':                     $crop_x=intval(($src_width-$crop_w)/2);                     $crop_y=$src_height-$crop_h;                     break;                 case 'south_east':                     $crop_x=$src_width-$crop_w;                     $crop_y=$src_height-$crop_h;                     break;                 default:                     $crop_x=intval(($src_width-$crop_w)/2);                     $crop_y=intval(($src_height-$crop_h)/2);             }             $image=$this->image;             $canvas=new Imagick();             if($this->type=='gif'){                 $images=$image->coalesceImages();                 foreach($images as $frame){                     $img=new Imagick();                     $img->readImageBlob($frame);                     $img->cropImage($crop_w,$crop_h,$crop_x,$crop_y);                     $img->thumbnailImage($width,$height,true);                     $canvas->addImage($img);                     $canvas->setImageDelay($img->getImageDelay());                     $canvas->setImagePage($width,$height,0,0);                 }             }else{                 $image->cropImage($crop_w,$crop_h,$crop_x,$crop_y);                 $image->thumbnailImage($width,$height,true);                 $canvas->addImage($image);                 $canvas->setImagePage($width,$height,0,0);             }             $image->destroy();             $this->image=$canvas;         }     }     /**         添加图片水印         参数:             $path:水印图片(包含完整路径)             $x,$y:水印座标     /**/     public function add_watermark($path,$x=0,$y=0){         $watermark=new Imagick($path);         $draw=new ImagickDraw();         $draw->composite($watermark->getImageCompose(),$x,$y,$watermark->getImageWidth(),$watermark->getimageheight(),$watermark);         if($this->type=='gif'){             $image=$this->image;             $canvas=new Imagick();             $images=$image->coalesceImages();             foreach($image as $frame){                 $img=new Imagick();                 $img->readImageBlob($frame);                 $img->drawImage($draw);                 $canvas->addImage($img);                 $canvas->setImageDelay($img->getImageDelay());             }             $image->destroy();             $this->image=$canvas;         }else{             $this->image->drawImage($draw);         }     }     /**         添加文字水印         参数:             $text:水印文字             $x,$y:水印座标     /**/     public function add_text($text,$x=0,$y=0,$angle=0,$style=array()){         $draw=new ImagickDraw();         if(isset($style['font'])) $draw->setFont($style['font']);         if(isset($style['font_size'])) $draw->setFontSize($style['font_size']);         if(isset($style['fill_color'])) $draw->setFillColor($style['fill_color']);         if(isset($style['under_color'])) $draw->setTextUnderColor($style['under_color']);         if($this->type=='gif'){             foreach($this->image as $frame){                 $frame->annotateImage($draw,$x,$y,$angle,$text);             }         }else{             $this->image->annotateImage($draw,$x,$y,$angle,$text);         }     }     /**         图片存档         参数:             $path:存档的位置和新的档案名     /**/     public function save_to($path){         $this->image->stripImage();         switch($this->type){         case 'gif':             $this->image->writeImages($path,true);             return ;         case 'jpg':         case 'jpeg':             $this->image->setImageCompressionQuality($_ENV['ImgQ']);             $this->image->writeImage($path);             return ;         case 'png':             $flag = $this->image->getImageAlphaChannel();             // 如果png背景不透明则压缩             if(imagick::ALPHACHANNEL_UNDEFINED == $flag or imagick::ALPHACHANNEL_DEACTIVATE == $flag){                 $this->image->setImageType(imagick::IMGTYPE_PALETTE);                 $this->image->writeImage($path);             }else{                 $this->image->writeImage($path);             }unset($flag);             return ;         default:             $this->image->writeImage($path);             return ;         }     }     // 直接输出图像到萤幕     public function output($header=true){         if($header) header('Content-type: '.$this->type);         echo $this->image->getImagesBlob();     }     /**         建立缩小图         $fit为真时,将保持比例并在$width X $height内產生缩小图     /**/     public function thumbnail($width=100,$height=100,$fit=true){$this->image->thumbnailImage($width,$height,$fit);}     /**         给图像添加边框         $width: 左右边框宽度         $height: 上下边框宽度         $color: 顏色     /**/     public function border($width,$height,$color='rgb(220,220,220)'){         $color=new ImagickPixel();         $color->setColor($color);         $this->image->borderImage($color,$width,$height);     }     //取得图像宽度     public function get_width(){$size=$this->image->getImagePage();return $size['width'];}     //取得图像高度     public function get_height(){$size=$this->image->getImagePage();return $size['height'];}     // 设置图像类型     public function set_type($type='png'){$this->type=$type;$this->image->setImageFormat($type);}     // 取得图像类型     public function get_type(){return $this->type;}     public function blur($radius,$sigma){$this->image->blurImage($radius,$sigma);} // 模糊     public function gaussian_blur($radius,$sigma){$this->image->gaussianBlurImage($radius,$sigma);} // 高斯模糊     public function motion_blur($radius,$sigma,$angle){$this->image->motionBlurImage($radius,$sigma,$angle);} // 运动模糊     public function radial_blur($radius){$this->image->radialBlurImage($radius);} // 径向模糊     public function add_noise($type=null){$this->image->addNoiseImage($type==null?imagick::NOISE_IMPULSE:$type);} // 添加噪点     public function level($black_point,$gamma,$white_point){$this->image->levelImage($black_point,$gamma,$white_point);} // 调整色阶     public function modulate($brightness,$saturation,$hue){$this->image->modulateImage($brightness,$saturation,$hue);} // 调整亮度,饱和度,色调     public function charcoal($radius,$sigma){$this->image->charcoalImage($radius,$sigma);} // 素描效果     public function oil_paint($radius){$this->image->oilPaintImage($radius);} // 油画效果     public function flop(){$this->image->flopImage();} // 水平翻转     public function flip(){$this->image->flipImage();} // 垂直翻转 }
状况二的解决办法如下: 首先用/usr/local/imagemagick/bin/convert -version指令查看一下输出内容是否已经开啟了多线程,Features:的值为空说明是单线程,如果Features:的值是openMP说明是多线程.imagick的多线程模式有一个bug,他会导致多核心的cpu使用率瞬间飆升到100所以一定要使用它的单线程模式才行.
[u]复制代码[/u] 代码如下:
Version: ImageMagick 6.7.1-2 2014-05-29 Q16 http://www.imagemagick.org Copyright: Copyright (C) 1999-2011 ImageMagick Studio LLC Features:  
 上边是我配置正确时显示的结果,如果没有配置正确会显示下边的结果
[u]复制代码[/u] 代码如下:
Version: ImageMagick 6.7.1-2 2014-05-29 Q16 http://www.imagemagick.org Copyright: Copyright (C) 1999-2011 ImageMagick Studio LLC Features: openMP
 第一种结果是单线程模式,第二种结果是多线程模式,因为imagick的多线程模式有bug,所以如果您刚开始是用多线程模式安装的imagick那就必须要yum remove imagemagick将其卸载掉重新安装才行. 经过重写class,重装imagick之后一切正常,而且处理图像的效能比之以前有了大幅提升  
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部