php建圖通常都用gd庫,因為是內置的不需要在服務器上額外安裝插件,所以用起來比較省心,但是如果你的程序主要的功能就是處理圖像,那麼就不建議用gd了,因為gd不但低效能而且能力也比較弱,佔用的系統資源也頗多,另外gd的creatfrom?也有bug,而imagick卻是一個很好的替代品,為此最近把我的一個項目由gd改成了imagick,但是改完之後出現了一些狀況在此分享給大家.
    首先說一下我這邊出現的狀況:
    狀況一:需要重寫圖像操作class
    狀況二:imagick多線程時會導致cpu使用率暴增到100%
    在此順便提一下imagick在centos6.4的安裝方法:
	1、安装imagemagick	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是否可以正常运行:	/usr/local/imagemagick/bin/convert -version	2、安装php扩展:imagick	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	/root/lnmp reload
接下來我們針對上述兩個狀況分別提出解決辦法:
狀況一的解決辦法如下:
  1 /**  2     imagick圖像處理類  3     用法:  4         //引入imagick物件  5         if(!defined('class_imagick')){require(inc.'class_imagick.php');}  6         $imagick=new class_imagick();  7         $imagick->open('a.gif');  8         $imagick->resize_to(100,100,'scale_fill');  9         $imagick->add_text('1024i.com',10,20); 10         $imagick->add_watermark('1024i.gif',10,50); 11         $imagick->save_to('x.gif'); 12         unset($imagick); 13 /**/ 14  15 define('class_imagick',true); 16 class class_imagick{ 17     private $image=null; 18     private $type=null; 19  20     // 構造 21     public function __construct(){} 22  23     // 析構 24     public function __destruct(){ 25         if($this->image!==null){$this->image->destroy();} 26     } 27  28     // 載入圖像 29     public function open($path){ 30         if(!file_exists($path)){ 31             $this->image=null; 32             return ; 33         } 34         $this->image=new imagick($path); 35         if($this->image){ 36             $this->type=strtolower($this->image->getimageformat()); 37         } 38         $this->image->stripimage(); 39         return $this->image; 40     } 41  42     /** 43         圖像裁切 44     /**/ 45     public function crop($x=0,$y=0,$width=null,$height=null){ 46         if($width==null) $width=$this->image->getimagewidth()-$x; 47         if($height==null) $height=$this->image->getimageheight()-$y; 48         if($widthimage; 52             $canvas=new imagick(); 53  54             $images=$image->coalesceimages(); 55             foreach($images as $frame){ 56                 $img=new imagick(); 57                 $img->readimageblob($frame); 58                 $img->cropimage($width,$height,$x,$y); 59  60                 $canvas->addimage($img); 61                 $canvas->setimagedelay($img->getimagedelay()); 62                 $canvas->setimagepage($width,$height,0,0); 63             } 64  65             $image->destroy(); 66             $this->image=$canvas; 67         }else{ 68             $this->image->cropimage($width,$height,$x,$y); 69         } 70     } 71  72     /** 73         更改圖像大小 74         參數: 75             $width:新的寬度 76             $height:新的高度 77             $fit: 適應大小 78                 'force': 把圖像強制改為$width x $height 79                 'scale': 按比例在$width x $height內縮放圖片,結果不完全等於$width x $height 80                 'scale_fill':按比例在$width x $height內縮放圖片,沒有像素的地方填充顏色$fill_color=array(255,255,255)(红,绿,蓝,透明度[0不透明-127全透明]) 81                 其他:智能模式,縮放圖片並從正中裁切$width x $height的大小 82         注意: 83             $fit='force','scale','scale_fill'時輸出完整圖像 84             $fit=圖像方位時輸出指定位置部份的圖像 85         字母與圖像的對應關係如下: 86             north_west   north   north_east 87             west         center        east 88             south_west   south   south_east 89     /**/ 90     public function resize_to($width=100,$height=100,$fit='center',$fill_color=array(255,255,255,0)){ 91         switch($fit){ 92         case 'force': 93             if($this->type=='gif'){ 94                 $image=$this->image; 95                 $canvas=new imagick(); 96  97                 $images=$image->coalesceimages(); 98                 foreach($images as $frame){ 99                     $img=new imagick();100                     $img->readimageblob($frame);101                     $img->thumbnailimage($width,$height,false);102 103                     $canvas->addimage($img);104                     $canvas->setimagedelay($img->getimagedelay());105                 }106                 $image->destroy();107                 $this->image=$canvas;108             }else{109                 $this->image->thumbnailimage($width,$height,false);110             }111             break;112         case 'scale':113             if($this->type=='gif'){114                 $image=$this->image;115                 $images=$image->coalesceimages();116                 $canvas=new imagick();117                 foreach($images as $frame){118                     $img=new imagick();119                     $img->readimageblob($frame);120                     $img->thumbnailimage($width,$height,true);121 122                     $canvas->addimage($img);123                     $canvas->setimagedelay($img->getimagedelay());124                 }125                 $image->destroy();126                 $this->image=$canvas;127             }else{128                 $this->image->thumbnailimage($width,$height,true);129             }130             break;131         case 'scale_fill':132             $size=$this->image->getimagepage();133             $src_width=$size['width'];134             $src_height=$size['height'];135 136             $x=0;137             $y=0;138 139             $dst_width=$width;140             $dst_height=$height;141 142             if($src_width*$height > $src_height*$width){143                 $dst_height=intval($width*$src_height/$src_width);144                 $y=intval(($height-$dst_height)/2);145             }else{146                 $dst_width=intval($height*$src_width/$src_height);147                 $x=intval(($width-$dst_width)/2);148             }149 150             $image=$this->image;151             $canvas=new imagick();152 153             $color='rgba('.$fill_color[0].','.$fill_color[1].','.$fill_color[2].','.$fill_color[3].')';154             if($this->type=='gif'){155                 $images=$image->coalesceimages();156                 foreach($images as $frame){157                     $frame->thumbnailimage($width,$height,true);158 159                     $draw=new imagickdraw();160                     $draw->composite($frame->getimagecompose(),$x,$y,$dst_width,$dst_height,$frame);161 162                     $img=new imagick();163                     $img->newimage($width,$height,$color,'gif');164                     $img->drawimage($draw);165 166                     $canvas->addimage($img);167                     $canvas->setimagedelay($img->getimagedelay());168                     $canvas->setimagepage($width,$height,0,0);169                 }170             }else{171                 $image->thumbnailimage($width,$height,true);172 173                 $draw=new imagickdraw();174                 $draw->composite($image->getimagecompose(),$x,$y,$dst_width,$dst_height,$image);175 176                 $canvas->newimage($width,$height,$color,$this->get_type());177                 $canvas->drawimage($draw);178                 $canvas->setimagepage($width,$height,0,0);179             }180             $image->destroy();181             $this->image=$canvas;182             break;183         default:184             $size=$this->image->getimagepage();185             $src_width=$size['width'];186             $src_height=$size['height'];187 188             $crop_x=0;189             $crop_y=0;190 191             $crop_w=$src_width;192             $crop_h=$src_height;193 194             if($src_width*$height > $src_height*$width){195                 $crop_w=intval($src_height*$width/$height);196             }else{197                 $crop_h=intval($src_width*$height/$width);198             }199 200             switch($fit){201                 case 'north_west':202                     $crop_x=0;203                     $crop_y=0;204                     break;205                 case 'north':206                     $crop_x=intval(($src_width-$crop_w)/2);207                     $crop_y=0;208                     break;209                 case 'north_east':210                     $crop_x=$src_width-$crop_w;211                     $crop_y=0;212                     break;213                 case 'west':214                     $crop_x=0;215                     $crop_y=intval(($src_height-$crop_h)/2);216                     break;217                 case 'center':218                     $crop_x=intval(($src_width-$crop_w)/2);219                     $crop_y=intval(($src_height-$crop_h)/2);220                     break;221                 case 'east':222                     $crop_x=$src_width-$crop_w;223                     $crop_y=intval(($src_height-$crop_h)/2);224                     break;225                 case 'south_west':226                     $crop_x=0;227                     $crop_y=$src_height-$crop_h;228                     break;229                 case 'south':230                     $crop_x=intval(($src_width-$crop_w)/2);231                     $crop_y=$src_height-$crop_h;232                     break;233                 case 'south_east':234                     $crop_x=$src_width-$crop_w;235                     $crop_y=$src_height-$crop_h;236                     break;237                 default:238                     $crop_x=intval(($src_width-$crop_w)/2);239                     $crop_y=intval(($src_height-$crop_h)/2);240             }241 242             $image=$this->image;243             $canvas=new imagick();244 245             if($this->type=='gif'){246                 $images=$image->coalesceimages();247                 foreach($images as $frame){248                     $img=new imagick();249                     $img->readimageblob($frame);250                     $img->cropimage($crop_w,$crop_h,$crop_x,$crop_y);251                     $img->thumbnailimage($width,$height,true);252 253                     $canvas->addimage($img);254                     $canvas->setimagedelay($img->getimagedelay());255                     $canvas->setimagepage($width,$height,0,0);256                 }257             }else{258                 $image->cropimage($crop_w,$crop_h,$crop_x,$crop_y);259                 $image->thumbnailimage($width,$height,true);260                 $canvas->addimage($image);261                 $canvas->setimagepage($width,$height,0,0);262             }263             $image->destroy();264             $this->image=$canvas;265         }266     }267 268     /**269         添加圖片水印270         參數:271             $path:水印圖片(包含完整路徑)272             $x,$y:水印座標273     /**/274     public function add_watermark($path,$x=0,$y=0){275         $watermark=new imagick($path);276         $draw=new imagickdraw();277         $draw->composite($watermark->getimagecompose(),$x,$y,$watermark->getimagewidth(),$watermark->getimageheight(),$watermark);278 279         if($this->type=='gif'){280             $image=$this->image;281             $canvas=new imagick();282             $images=$image->coalesceimages();283             foreach($image as $frame){284                 $img=new imagick();285                 $img->readimageblob($frame);286                 $img->drawimage($draw);287 288                 $canvas->addimage($img);289                 $canvas->setimagedelay($img->getimagedelay());290             }291             $image->destroy();292             $this->image=$canvas;293         }else{294             $this->image->drawimage($draw);295         }296     }297 298     /**299         添加文字水印300         參數:301             $text:水印文字302             $x,$y:水印座標303     /**/304     public function add_text($text,$x=0,$y=0,$angle=0,$style=array()){305         $draw=new imagickdraw();306         if(isset($style['font'])) $draw->setfont($style['font']);307         if(isset($style['font_size'])) $draw->setfontsize($style['font_size']);308         if(isset($style['fill_color'])) $draw->setfillcolor($style['fill_color']);309         if(isset($style['under_color'])) $draw->settextundercolor($style['under_color']);310 311         if($this->type=='gif'){312             foreach($this->image as $frame){313                 $frame->annotateimage($draw,$x,$y,$angle,$text);314             }315         }else{316             $this->image->annotateimage($draw,$x,$y,$angle,$text);317         }318     }319 320     /**321         圖片存檔322         參數:323             $path:存檔的位置和新的檔案名324     /**/325     public function save_to($path){326         $this->image->stripimage();327         switch($this->type){328         case 'gif':329             $this->image->writeimages($path,true);330             return ;331         case 'jpg':332         case 'jpeg':333             $this->image->setimagecompressionquality($_env['imgq']);334             $this->image->writeimage($path);335             return ;336         case 'png':337             $flag = $this->image->getimagealphachannel();338 339             // 如果png背景不透明則壓縮340             if(imagick::alphachannel_undefined == $flag or imagick::alphachannel_deactivate == $flag){341                 $this->image->setimagetype(imagick::imgtype_palette);342                 $this->image->writeimage($path);343             }else{344                 $this->image->writeimage($path);345             }unset($flag);346             return ;347         default:348             $this->image->writeimage($path);349             return ;350         }351     }352 353     // 直接輸出圖像到螢幕354     public function output($header=true){355         if($header) header('content-type: '.$this->type);356         echo $this->image->getimagesblob();357     }358 359     /**360         建立縮小圖361         $fit為真時,將保持比例並在$width x $height内產生縮小圖362     /**/363     public function thumbnail($width=100,$height=100,$fit=true){$this->image->thumbnailimage($width,$height,$fit);}364 365     /**366         給圖像添加邊框367         $width: 左右邊框寬度368         $height: 上下邊框寬度369         $color: 顏色370     /**/371     public function border($width,$height,$color='rgb(220,220,220)'){372         $color=new imagickpixel();373         $color->setcolor($color);374         $this->image->borderimage($color,$width,$height);375     }376 377     //取得圖像寬度378     public function get_width(){$size=$this->image->getimagepage();return $size['width'];}379 380     //取得圖像高度381     public function get_height(){$size=$this->image->getimagepage();return $size['height'];}382 383     // 設置圖像類型384     public function set_type($type='png'){$this->type=$type;$this->image->setimageformat($type);}385 386     // 取得圖像類型387     public function get_type(){return $this->type;}388 389     public function blur($radius,$sigma){$this->image->blurimage($radius,$sigma);} // 模糊390     public function gaussian_blur($radius,$sigma){$this->image->gaussianblurimage($radius,$sigma);} // 高斯模糊391     public function motion_blur($radius,$sigma,$angle){$this->image->motionblurimage($radius,$sigma,$angle);} // 運動模糊392     public function radial_blur($radius){$this->image->radialblurimage($radius);} // 徑向模糊393     public function add_noise($type=null){$this->image->addnoiseimage($type==null?imagick::noise_impulse:$type);} // 添加噪點394     public function level($black_point,$gamma,$white_point){$this->image->levelimage($black_point,$gamma,$white_point);} // 調整色階395     public function modulate($brightness,$saturation,$hue){$this->image->modulateimage($brightness,$saturation,$hue);} // 調整亮度,飽和度,色調396     public function charcoal($radius,$sigma){$this->image->charcoalimage($radius,$sigma);} // 素描效果397     public function oil_paint($radius){$this->image->oilpaintimage($radius);} // 油畫效果398     public function flop(){$this->image->flopimage();} // 水平翻轉399     public function flip(){$this->image->flipimage();} // 垂直翻轉400 }view code狀況二的解決辦法如下:
首先用/usr/local/imagemagick/bin/convert -version指令查看一下輸出內容是否已經開啟了多線程,features:的值為空說明是單線程,如果features:的值是openmp說明是多線程.imagick的多線程模式有一個bug,他會導致多核心的cpu使用率瞬間飆升到100%.所以一定要使用它的單線程模式才行.
version: imagemagick 6.7.1-2 2014-05-29 q16 http://www.imagemagick.orgcopyright: copyright (c) 1999-2011 imagemagick studio llcfeatures:    
上邊是我配置正確時顯示的結果,如果沒有配置正確會顯示下邊的結果
version: imagemagick 6.7.1-2 2014-05-29 q16 http://www.imagemagick.orgcopyright: copyright (c) 1999-2011 imagemagick studio llcfeatures: openmp
第一種結果是單線程模式,第二種結果是多線程模式,因為imagick的多線程模式有bug,所以如果您剛開始是用多線程模式安裝的imagick那就必須要yum remove imagemagick將其卸載掉重新安裝才行.
經過重寫class,重裝imagick之後一切正常,而且處理圖像的效能比之以前有了大幅提升
http://www.bkjia.com/phpjc/778220.htmlwww.bkjia.comtruehttp://www.bkjia.com/phpjc/778220.htmltecharticlephp建圖通常都用gd庫,因為是內置的不需要在服務器上額外安裝插件,所以用起來比較省心,但是如果你的程序主要的功能就是處理圖像,那麼就...
   
 
   