搜尋
首頁後端開發php教程關於imagick不得不說的一些事_PHP教程

    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

 

    接下來我們針對上述兩個狀況分別提出解決辦法:

狀況一的解決辦法如下:

關於imagick不得不說的一些事_PHP教程 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$heightreturn; 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->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.org
Copyright: Copyright (C) 1999-2011 ImageMagick Studio LLC
Features:    

 上邊是我配置正確時顯示的結果,如果沒有配置正確會顯示下邊的結果

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之後一切正常,而且處理圖像的效能比之以前有了大幅提升

 

 

 

 

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/778220.htmlTechArticlePHP建圖通常都用GD庫,因為是內置的不需要在服務器上額外安裝插件,所以用起來比較省心,但是如果你的程序主要的功能就是處理圖像,那麼就...
陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
php怎么把负数转为正整数php怎么把负数转为正整数Apr 19, 2022 pm 08:59 PM

php把负数转为正整数的方法:1、使用abs()函数将负数转为正数,使用intval()函数对正数取整,转为正整数,语法“intval(abs($number))”;2、利用“~”位运算符将负数取反加一,语法“~$number + 1”。

php怎么实现几秒后执行一个函数php怎么实现几秒后执行一个函数Apr 24, 2022 pm 01:12 PM

实现方法:1、使用“sleep(延迟秒数)”语句,可延迟执行函数若干秒;2、使用“time_nanosleep(延迟秒数,延迟纳秒数)”语句,可延迟执行函数若干秒和纳秒;3、使用“time_sleep_until(time()+7)”语句。

php怎么除以100保留两位小数php怎么除以100保留两位小数Apr 22, 2022 pm 06:23 PM

php除以100保留两位小数的方法:1、利用“/”运算符进行除法运算,语法“数值 / 100”;2、使用“number_format(除法结果, 2)”或“sprintf("%.2f",除法结果)”语句进行四舍五入的处理值,并保留两位小数。

php怎么根据年月日判断是一年的第几天php怎么根据年月日判断是一年的第几天Apr 22, 2022 pm 05:02 PM

判断方法:1、使用“strtotime("年-月-日")”语句将给定的年月日转换为时间戳格式;2、用“date("z",时间戳)+1”语句计算指定时间戳是一年的第几天。date()返回的天数是从0开始计算的,因此真实天数需要在此基础上加1。

php怎么替换nbsp空格符php怎么替换nbsp空格符Apr 24, 2022 pm 02:55 PM

方法:1、用“str_replace(" ","其他字符",$str)”语句,可将nbsp符替换为其他字符;2、用“preg_replace("/(\s|\&nbsp\;||\xc2\xa0)/","其他字符",$str)”语句。

php怎么判断有没有小数点php怎么判断有没有小数点Apr 20, 2022 pm 08:12 PM

php判断有没有小数点的方法:1、使用“strpos(数字字符串,'.')”语法,如果返回小数点在字符串中第一次出现的位置,则有小数点;2、使用“strrpos(数字字符串,'.')”语句,如果返回小数点在字符串中最后一次出现的位置,则有。

php字符串有没有下标php字符串有没有下标Apr 24, 2022 am 11:49 AM

php字符串有下标。在PHP中,下标不仅可以应用于数组和对象,还可应用于字符串,利用字符串的下标和中括号“[]”可以访问指定索引位置的字符,并对该字符进行读写,语法“字符串名[下标值]”;字符串的下标值(索引值)只能是整数类型,起始值为0。

php怎么读取字符串后几个字符php怎么读取字符串后几个字符Apr 22, 2022 pm 08:31 PM

在php中,可以使用substr()函数来读取字符串后几个字符,只需要将该函数的第二个参数设置为负值,第三个参数省略即可;语法为“substr(字符串,-n)”,表示读取从字符串结尾处向前数第n个字符开始,直到字符串结尾的全部字符。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前By尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器