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图像处理类
用法:
//引入Imagick物件
if(!defined('CLASS_IMAGICK')){require(Inc.'class_imagick.php');}
$Imagick=new class_imagick();
$Imagick->open('a.gif');
$Imagick->resize_to(100,100,'scale_fill');
$Imagick->add_text('1024i.com',10,20);
$Imagick->add_watermark('1024i.gif',10,50);
$Imagick->save_to('x.gif');
unset($Imagick);
/**/
define('CLASS_IMAGICK',TRUE);
class class_imagick{
private $image=null;
private $type=null;
// 构造
public function __construct(){}
// 析构
public function __destruct(){
if($this->image!==null){$this->image->destroy();}
}
// 载入图像
public function open($path){
if(!file_exists($path)){
$this->image=null;
return ;
}
$this->image=new Imagick($path);
if($this->image){
$this->type=strtolower($this->image->getImageFormat());
}
$this->image->stripImage();
return $this->image;
}
/**
图像裁切
/**/
public function crop($x=0,$y=0,$width=null,$height=null){
if($width==null) $width=$this->image->getImageWidth()-$x;
if($height==null) $height=$this->image->getImageHeight()-$y;
if($width if($this->type=='gif'){
$image=$this->image;
$canvas=new Imagick();
$images=$image->coalesceImages();
foreach($images as $frame){
$img=new Imagick();
$img->readImageBlob($frame);
$img->cropImage($width,$height,$x,$y);
$canvas->addImage($img);
$canvas->setImageDelay($img->getImageDelay());
$canvas->setImagePage($width,$height,0,0);
}
$image->destroy();
$this->image=$canvas;
}else{
$this->image->cropImage($width,$height,$x,$y);
}
}
/**
更改图像大小
参数:
$width:新的宽度
$height:新的高度
$fit: 适应大小
'force': 把图像强制改为$width X $height
'scale': 按比例在$width X $height内缩放图片,结果不完全等於$width X $height
'scale_fill':按比例在$width X $height内缩放图片,没有像素的地方填充顏色$fill_color=array(255,255,255)(红,绿,蓝,透明度[0不透明-127全透明])
其他:智能模式,缩放图片并从正中裁切$width X $height的大小
注意:
$fit='force','scale','scale_fill'时输出完整图像
$fit=图像方位时输出指定位置部份的图像
字母与图像的对应关系如下:
north_west north north_east
west center east
south_west south south_east
/**/
public function resize_to($width=100,$height=100,$fit='center',$fill_color=array(255,255,255,0)){
switch($fit){
case 'force':
if($this->type=='gif'){
$image=$this->image;
$canvas=new Imagick();
$images=$image->coalesceImages();
foreach($images as $frame){
$img=new Imagick();
$img->readImageBlob($frame);
$img->thumbnailImage($width,$height,false);
$canvas->addImage($img);
$canvas->setImageDelay($img->getImageDelay());
}
$image->destroy();
$this->image=$canvas;
}else{
$this->image->thumbnailImage($width,$height,false);
}
break;
case 'scale':
if($this->type=='gif'){
$image=$this->image;
$images=$image->coalesceImages();
$canvas=new Imagick();
foreach($images as $frame){
$img=new Imagick();
$img->readImageBlob($frame);
$img->thumbnailImage($width,$height,true);
$canvas->addImage($img);
$canvas->setImageDelay($img->getImageDelay());
}
$image->destroy();
$this->image=$canvas;
}else{
$this->image->thumbnailImage($width,$height,true);
}
break;
case 'scale_fill':
$size=$this->image->getImagePage();
$src_width=$size['width'];
$src_height=$size['height'];
$x=0;
$y=0;
$dst_width=$width;
$dst_height=$height;
if($src_width*$height > $src_height*$width){
$dst_height=intval($width*$src_height/$src_width);
$y=intval(($height-$dst_height)/2);
}else{
$dst_width=intval($height*$src_width/$src_height);
$x=intval(($width-$dst_width)/2);
}
$image=$this->image;
$canvas=new Imagick();
$color='rgba('.$fill_color[0].','.$fill_color[1].','.$fill_color[2].','.$fill_color[3].')';
if($this->type=='gif'){
$images=$image->coalesceImages();
foreach($images as $frame){
$frame->thumbnailImage($width,$height,true);
$draw=new ImagickDraw();
$draw->composite($frame->getImageCompose(),$x,$y,$dst_width,$dst_height,$frame);
$img=new Imagick();
$img->newImage($width,$height,$color,'gif');
$img->drawImage($draw);
$canvas->addImage($img);
$canvas->setImageDelay($img->getImageDelay());
$canvas->setImagePage($width,$height,0,0);
}
}else{
$image->thumbnailImage($width,$height,true);
$draw=new ImagickDraw();
$draw->composite($image->getImageCompose(),$x,$y,$dst_width,$dst_height,$image);
$canvas->newImage($width,$height,$color,$this->get_type());
$canvas->drawImage($draw);
$canvas->setImagePage($width,$height,0,0);
}
$image->destroy();
$this->image=$canvas;
break;
default:
$size=$this->image->getImagePage();
$src_width=$size['width'];
$src_height=$size['height'];
$crop_x=0;
$crop_y=0;
$crop_w=$src_width;
$crop_h=$src_height;
if($src_width*$height > $src_height*$width){
$crop_w=intval($src_height*$width/$height);
}else{
$crop_h=intval($src_width*$height/$width);
}
switch($fit){
case 'north_west':
$crop_x=0;
$crop_y=0;
break;
case 'north':
$crop_x=intval(($src_width-$crop_w)/2);
$crop_y=0;
break;
case 'north_east':
$crop_x=$src_width-$crop_w;
$crop_y=0;
break;
case 'west':
$crop_x=0;
$crop_y=intval(($src_height-$crop_h)/2);
break;
case 'center':
$crop_x=intval(($src_width-$crop_w)/2);
$crop_y=intval(($src_height-$crop_h)/2);
break;
case 'east':
$crop_x=$src_width-$crop_w;
$crop_y=intval(($src_height-$crop_h)/2);
break;
case 'south_west':
$crop_x=0;
$crop_y=$src_height-$crop_h;
break;
case 'south':
$crop_x=intval(($src_width-$crop_w)/2);
$crop_y=$src_height-$crop_h;
break;
case 'south_east':
$crop_x=$src_width-$crop_w;
$crop_y=$src_height-$crop_h;
break;
default:
$crop_x=intval(($src_width-$crop_w)/2);
$crop_y=intval(($src_height-$crop_h)/2);
}
$image=$this->image;
$canvas=new Imagick();
if($this->type=='gif'){
$images=$image->coalesceImages();
foreach($images as $frame){
$img=new Imagick();
$img->readImageBlob($frame);
$img->cropImage($crop_w,$crop_h,$crop_x,$crop_y);
$img->thumbnailImage($width,$height,true);
$canvas->addImage($img);
$canvas->setImageDelay($img->getImageDelay());
$canvas->setImagePage($width,$height,0,0);
}
}else{
$image->cropImage($crop_w,$crop_h,$crop_x,$crop_y);
$image->thumbnailImage($width,$height,true);
$canvas->addImage($image);
$canvas->setImagePage($width,$height,0,0);
}
$image->destroy();
$this->image=$canvas;
}
}
/**
添加图片水印
参数:
$path:水印图片(包含完整路径)
$x,$y:水印座标
/**/
public function add_watermark($path,$x=0,$y=0){
$watermark=new Imagick($path);
$draw=new ImagickDraw();
$draw->composite($watermark->getImageCompose(),$x,$y,$watermark->getImageWidth(),$watermark->getimageheight(),$watermark);
if($this->type=='gif'){
$image=$this->image;
$canvas=new Imagick();
$images=$image->coalesceImages();
foreach($image as $frame){
$img=new Imagick();
$img->readImageBlob($frame);
$img->drawImage($draw);
$canvas->addImage($img);
$canvas->setImageDelay($img->getImageDelay());
}
$image->destroy();
$this->image=$canvas;
}else{
$this->image->drawImage($draw);
}
}
/**
添加文字水印
参数:
$text:水印文字
$x,$y:水印座标
/**/
public function add_text($text,$x=0,$y=0,$angle=0,$style=array()){
$draw=new ImagickDraw();
if(isset($style['font'])) $draw->setFont($style['font']);
if(isset($style['font_size'])) $draw->setFontSize($style['font_size']);
if(isset($style['fill_color'])) $draw->setFillColor($style['fill_color']);
if(isset($style['under_color'])) $draw->setTextUnderColor($style['under_color']);
if($this->type=='gif'){
foreach($this->image as $frame){
$frame->annotateImage($draw,$x,$y,$angle,$text);
}
}else{
$this->image->annotateImage($draw,$x,$y,$angle,$text);
}
}
/**
图片存档
参数:
$path:存档的位置和新的档案名
/**/
public function save_to($path){
$this->image->stripImage();
switch($this->type){
case 'gif':
$this->image->writeImages($path,true);
return ;
case 'jpg':
case 'jpeg':
$this->image->setImageCompressionQuality($_ENV['ImgQ']);
$this->image->writeImage($path);
return ;
case 'png':
$flag = $this->image->getImageAlphaChannel();
// 如果png背景不透明则压缩
if(imagick::ALPHACHANNEL_UNDEFINED == $flag or imagick::ALPHACHANNEL_DEACTIVATE == $flag){
$this->image->setImageType(imagick::IMGTYPE_PALETTE);
$this->image->writeImage($path);
}else{
$this->image->writeImage($path);
}unset($flag);
return ;
default:
$this->image->writeImage($path);
return ;
}
}
// 直接输出图像到萤幕
public function output($header=true){
if($header) header('Content-type: '.$this->type);
echo $this->image->getImagesBlob();
}
/**
建立缩小图
$fit为真时,将保持比例并在$width X $height内產生缩小图
/**/
public function thumbnail($width=100,$height=100,$fit=true){$this->image->thumbnailImage($width,$height,$fit);}
/**
给图像添加边框
$width: 左右边框宽度
$height: 上下边框宽度
$color: 顏色
/**/
public function border($width,$height,$color='rgb(220,220,220)'){
$color=new ImagickPixel();
$color->setColor($color);
$this->image->borderImage($color,$width,$height);
}
//取得图像宽度
public function get_width(){$size=$this->image->getImagePage();return $size['width'];}
//取得图像高度
public function get_height(){$size=$this->image->getImagePage();return $size['height'];}
// 设置图像类型
public function set_type($type='png'){$this->type=$type;$this->image->setImageFormat($type);}
// 取得图像类型
public function get_type(){return $this->type;}
public function blur($radius,$sigma){$this->image->blurImage($radius,$sigma);} // 模糊
public function gaussian_blur($radius,$sigma){$this->image->gaussianBlurImage($radius,$sigma);} // 高斯模糊
public function motion_blur($radius,$sigma,$angle){$this->image->motionBlurImage($radius,$sigma,$angle);} // 运动模糊
public function radial_blur($radius){$this->image->radialBlurImage($radius);} // 径向模糊
public function add_noise($type=null){$this->image->addNoiseImage($type==null?imagick::NOISE_IMPULSE:$type);} // 添加噪点
public function level($black_point,$gamma,$white_point){$this->image->levelImage($black_point,$gamma,$white_point);} // 调整色阶
public function modulate($brightness,$saturation,$hue){$this->image->modulateImage($brightness,$saturation,$hue);} // 调整亮度,饱和度,色调
public function charcoal($radius,$sigma){$this->image->charcoalImage($radius,$sigma);} // 素描效果
public function oil_paint($radius){$this->image->oilPaintImage($radius);} // 油画效果
public function flop(){$this->image->flopImage();} // 水平翻转
public function flip(){$this->image->flipImage();} // 垂直翻转
}
状况二的解决办法如下:
首先用/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之后一切正常,而且处理图像的效能比之以前有了大幅提升

TomakePHPapplicationsfaster,followthesesteps:1)UseOpcodeCachinglikeOPcachetostoreprecompiledscriptbytecode.2)MinimizeDatabaseQueriesbyusingquerycachingandefficientindexing.3)LeveragePHP7 Featuresforbettercodeefficiency.4)ImplementCachingStrategiessuc

ToimprovePHPapplicationspeed,followthesesteps:1)EnableopcodecachingwithAPCutoreducescriptexecutiontime.2)ImplementdatabasequerycachingusingPDOtominimizedatabasehits.3)UseHTTP/2tomultiplexrequestsandreduceconnectionoverhead.4)Limitsessionusagebyclosin

Dependency injection (DI) significantly improves the testability of PHP code by explicitly transitive dependencies. 1) DI decoupling classes and specific implementations make testing and maintenance more flexible. 2) Among the three types, the constructor injects explicit expression dependencies to keep the state consistent. 3) Use DI containers to manage complex dependencies to improve code quality and development efficiency.

DatabasequeryoptimizationinPHPinvolvesseveralstrategiestoenhanceperformance.1)Selectonlynecessarycolumnstoreducedatatransfer.2)Useindexingtospeedupdataretrieval.3)Implementquerycachingtostoreresultsoffrequentqueries.4)Utilizepreparedstatementsforeffi

PHPisusedforsendingemailsduetoitsbuilt-inmail()functionandsupportivelibrarieslikePHPMailerandSwiftMailer.1)Usethemail()functionforbasicemails,butithaslimitations.2)EmployPHPMailerforadvancedfeatureslikeHTMLemailsandattachments.3)Improvedeliverability

PHP performance bottlenecks can be solved through the following steps: 1) Use Xdebug or Blackfire for performance analysis to find out the problem; 2) Optimize database queries and use caches, such as APCu; 3) Use efficient functions such as array_filter to optimize array operations; 4) Configure OPcache for bytecode cache; 5) Optimize the front-end, such as reducing HTTP requests and optimizing pictures; 6) Continuously monitor and optimize performance. Through these methods, the performance of PHP applications can be significantly improved.

DependencyInjection(DI)inPHPisadesignpatternthatmanagesandreducesclassdependencies,enhancingcodemodularity,testability,andmaintainability.Itallowspassingdependencieslikedatabaseconnectionstoclassesasparameters,facilitatingeasiertestingandscalability.

CachingimprovesPHPperformancebystoringresultsofcomputationsorqueriesforquickretrieval,reducingserverloadandenhancingresponsetimes.Effectivestrategiesinclude:1)Opcodecaching,whichstorescompiledPHPscriptsinmemorytoskipcompilation;2)DatacachingusingMemc


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

EditPlus Chinese cracked version
Small size, syntax highlighting, does not support code prompt function

SublimeText3 English version
Recommended: Win version, supports code prompts!

PhpStorm Mac version
The latest (2018.2.1) professional PHP integrated development tool

Dreamweaver Mac version
Visual web development tools

Safe Exam Browser
Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.
