백엔드 개발 PHP 튜토리얼 關於imagick不得不說的一些事_PHP教程

關於imagick不得不說的一些事_PHP教程

Jul 13, 2016 am 10:29 AM
imagemagick 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<=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->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으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

CakePHP 프로젝트 구성 CakePHP 프로젝트 구성 Sep 10, 2024 pm 05:25 PM

이번 장에서는 CakePHP의 환경 변수, 일반 구성, 데이터베이스 구성, 이메일 구성에 대해 알아봅니다.

Ubuntu 및 Debian용 PHP 8.4 설치 및 업그레이드 가이드 Ubuntu 및 Debian용 PHP 8.4 설치 및 업그레이드 가이드 Dec 24, 2024 pm 04:42 PM

PHP 8.4는 상당한 양의 기능 중단 및 제거를 통해 몇 가지 새로운 기능, 보안 개선 및 성능 개선을 제공합니다. 이 가이드에서는 Ubuntu, Debian 또는 해당 파생 제품에서 PHP 8.4를 설치하거나 PHP 8.4로 업그레이드하는 방법을 설명합니다.

CakePHP 날짜 및 시간 CakePHP 날짜 및 시간 Sep 10, 2024 pm 05:27 PM

cakephp4에서 날짜와 시간을 다루기 위해 사용 가능한 FrozenTime 클래스를 활용하겠습니다.

CakePHP 파일 업로드 CakePHP 파일 업로드 Sep 10, 2024 pm 05:27 PM

파일 업로드 작업을 위해 양식 도우미를 사용할 것입니다. 다음은 파일 업로드의 예입니다.

CakePHP 라우팅 CakePHP 라우팅 Sep 10, 2024 pm 05:25 PM

이번 장에서는 라우팅과 관련된 다음과 같은 주제를 학습하겠습니다.

CakePHP 토론 CakePHP 토론 Sep 10, 2024 pm 05:28 PM

CakePHP는 PHP용 오픈 소스 프레임워크입니다. 이는 애플리케이션을 훨씬 쉽게 개발, 배포 및 유지 관리할 수 있도록 하기 위한 것입니다. CakePHP는 강력하고 이해하기 쉬운 MVC와 유사한 아키텍처를 기반으로 합니다. 모델, 뷰 및 컨트롤러 gu

PHP 개발을 위해 Visual Studio Code(VS Code)를 설정하는 방법 PHP 개발을 위해 Visual Studio Code(VS Code)를 설정하는 방법 Dec 20, 2024 am 11:31 AM

VS Code라고도 알려진 Visual Studio Code는 모든 주요 운영 체제에서 사용할 수 있는 무료 소스 코드 편집기 또는 통합 개발 환경(IDE)입니다. 다양한 프로그래밍 언어에 대한 대규모 확장 모음을 통해 VS Code는

CakePHP 유효성 검사기 만들기 CakePHP 유효성 검사기 만들기 Sep 10, 2024 pm 05:26 PM

컨트롤러에 다음 두 줄을 추가하면 유효성 검사기를 만들 수 있습니다.

See all articles