php建圖通常都用GD庫,因為是內置的不需要在服務器上額外安裝插件,所以用起來比較省心,但是如果你的程序主要的功能就是處理圖像,那麼就不建議用GD了,因為GD不但低效能而且能力也比較弱,佔用的系統資源也頗多,另外GD的creatfrom???也有bug,而imagick卻是一個很好的替代品,為此最近把我的一個項目由GD改成了imagick,但是改完之後出現了一些狀況在此分享給大家.
首先說一下我這邊出現的狀況:
狀況一:需要重寫圖像操作class
狀況二:imagick多線程時會導致cpu使用率暴增到100%
在此順便提一下imagick在centos6.4的安裝方法:
1、安装ImageMagickwget http://soft.vpser.net/web/imagemagick/ImageMagick-6.7.1-2.tar.gztar zxvf ImageMagick-6.7.1-2.tar.gzcd ImageMagick-6.7.1-2/./configure --PRefix=/usr/local/imagemagick --disable-openmpmake && make installldconfig测试ImageMagick是否可以正常运行:/usr/local/imagemagick/bin/convert -version2、安装PHP扩展:imagickwget http://pecl.php.net/get/imagick-3.0.1.tgztar zxvf imagick-3.0.1.tgzcd imagick-3.0.1//usr/local/php/bin/phpize./configure --with-php-config=/usr/local/php/bin/php-config --with-imagick=/usr/local/imagemagickmake && make installldconfigvi /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($width<=0 || $height<=0) return; 49 50 if($this->type=='gif'){ 51 $image=$this->image; 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->drawI