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庫,因為是內置的不需要在服務器上額外安裝插件,所以用起來比較省心,但是如果你的程序主要的功能就是處理圖像,那麼就...