Maison php教程 php手册 關於imagick不得不說的一些事

關於imagick不得不說的一些事

Jun 13, 2016 am 09:34 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
Copier après la connexion

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

狀況一的解決辦法如下:

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:    
Copier après la connexion

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

Version: ImageMagick 6.7.1-2 2014-05-29 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2011 ImageMagick Studio LLC
Features: openMP
Copier après la connexion

 第一種結果是單線程模式,第二種結果是多線程模式,因為imagick的多線程模式有bug,所以如果您剛開始是用多線程模式安裝的imagick那就必須要yum remove imagemagick將其卸載掉重新安裝才行.

經過重寫class,重裝imagick之後一切正常,而且處理圖像的效能比之以前有了大幅提升

 

 

 

 

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Comment déverrouiller tout dans Myrise
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Guide d'installation et de mise à niveau de PHP 8.4 pour Ubuntu et Debian Guide d'installation et de mise à niveau de PHP 8.4 pour Ubuntu et Debian Dec 24, 2024 pm 04:42 PM

PHP 8.4 apporte plusieurs nouvelles fonctionnalités, améliorations de sécurité et de performances avec une bonne quantité de dépréciations et de suppressions de fonctionnalités. Ce guide explique comment installer PHP 8.4 ou mettre à niveau vers PHP 8.4 sur Ubuntu, Debian ou leurs dérivés. Bien qu'il soit possible de compiler PHP à partir des sources, son installation à partir d'un référentiel APT comme expliqué ci-dessous est souvent plus rapide et plus sécurisée car ces référentiels fourniront les dernières corrections de bogues et mises à jour de sécurité à l'avenir.

CakePHP travaillant avec la base de données CakePHP travaillant avec la base de données Sep 10, 2024 pm 05:25 PM

Travailler avec la base de données dans CakePHP est très simple. Nous comprendrons les opérations CRUD (Créer, Lire, Mettre à jour, Supprimer) dans ce chapitre.

Date et heure de CakePHP Date et heure de CakePHP Sep 10, 2024 pm 05:27 PM

Pour travailler avec la date et l'heure dans cakephp4, nous allons utiliser la classe FrozenTime disponible.

Téléchargement de fichiers CakePHP Téléchargement de fichiers CakePHP Sep 10, 2024 pm 05:27 PM

Pour travailler sur le téléchargement de fichiers, nous allons utiliser l'assistant de formulaire. Voici un exemple de téléchargement de fichiers.

Discuter de CakePHP Discuter de CakePHP Sep 10, 2024 pm 05:28 PM

CakePHP est un framework open source pour PHP. Il vise à faciliter grandement le développement, le déploiement et la maintenance d'applications. CakePHP est basé sur une architecture de type MVC à la fois puissante et facile à appréhender. Modèles, vues et contrôleurs gu

CakePHP créant des validateurs CakePHP créant des validateurs Sep 10, 2024 pm 05:26 PM

Le validateur peut être créé en ajoutant les deux lignes suivantes dans le contrôleur.

Journalisation CakePHP Journalisation CakePHP Sep 10, 2024 pm 05:26 PM

Se connecter à CakePHP est une tâche très simple. Il vous suffit d'utiliser une seule fonction. Vous pouvez enregistrer les erreurs, les exceptions, les activités des utilisateurs, les actions entreprises par les utilisateurs, pour tout processus en arrière-plan comme cronjob. La journalisation des données dans CakePHP est facile. La fonction log() est fournie

Comment configurer Visual Studio Code (VS Code) pour le développement PHP Comment configurer Visual Studio Code (VS Code) pour le développement PHP Dec 20, 2024 am 11:31 AM

Visual Studio Code, également connu sous le nom de VS Code, est un éditeur de code source gratuit – ou environnement de développement intégré (IDE) – disponible pour tous les principaux systèmes d'exploitation. Avec une large collection d'extensions pour de nombreux langages de programmation, VS Code peut être c

See all articles