The GD library is usually used for PHP mapping. Because it is built-in and does not require additional plug-ins to be installed on the server, it is more worry-free to use. However, if the main function of your program is to process images, then it is not recommended to use GD. Because GD is not only inefficient and weak in capabilities, but also takes up a lot of system resources. In addition, GD's creatfrom also has bugs, but imagick is a good substitute. For this reason, I recently changed one of my projects from GD. It became imagick, but after the change, some situations occurred and I would like to share them with you here.
First of all, let me talk about the situation here:
Situation 1: Image operation class needs to be rewritten
Situation 2: Multi-threading of imagick will cause the CPU usage to surge to 100%
By the way, here’s how to install imagick on centos6.4:
1. Install ImageMagick
Copy code The code is as follows:
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
Test whether ImageMagick works properly:
Copy code The code is as follows:
/usr/local/imagemagick/bin/convert -version
2. Install PHP extension: imagick
Copy code The code is as follows:
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
Add: extension = "imagick.so"
Restart lnmp
Copy code The code is as follows:
/root/lnmp reload
Next we propose solutions to the above two situations:
The solution to situation 1 is as follows:
Copy code The code is as follows:
/**
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;
}
/**
Image cropping
/**/
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<=0 || $height<=0) return;
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);
}
}
/**
Change the image size
Parameters:
$width: New width
$height: New height
$fit: Fit size
'force': Force the image to $ width Fill in the color $ fill_color = Array (255,255,255) (red, green, blue, transparency [0 opaque -127 fully transparent])
other: other: smart mode, cutting $ width x $ The size of height
Note:
$ FIT = 'Force', 'SCALE', 'SCALE_FILL' When outputs the full image
$ FIT = the image of the specified position when outputs the position of the position
Letter and letters and letters and letters and letters and letters and letters and letters and letters and letters and letters The correspondence between the images is as follows:
north_west north north_east
west west center
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;
}
}
/**
Add image watermark
Parameters:
$path: watermark image (including full path)
$x,$y: watermark coordinates
/**/
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);
}
}
/**
Add text watermark
Parameters:
$text: Watermark text
$x,$y: Watermark coordinates
/**/
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);
}
}
/**
Image archive
Parameters:
$path: Archive location and new file name
/**/
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();
}
/**
Create a reduced image
When $fit is true, the proportion will be maintained and a reduced image will be generated within $width X $height
/**/
public function thumbnail($width=100,$height=100,$fit=true){$this->image->thumbnailImage($width,$height,$fit);}
/**
Add a border to the image
$width: Left and right border width
$height: Top and bottom border width
$color: 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);}// Gaussian blur
public function motion_blur($radius,$sigma,$angle){$this->image->motionBlurImage($radius,$sigma,$angle);} // Motion blur
public function radial_blur($radius){$this->image->radialBlurImage($radius);} // Radial blur
public function add_noise($type=null){$this->image-> ;addNoiseImage($type==null?imagick::NOISE_IMPULSE:$type);} // Add noise
public function level($black_point,$gamma,$white_point){$this->image->levelImage ($black_point,$gamma,$white_point);} // Adjust the color level
public function modulate($brightness,$saturation,$hue){$this->image->modulateImage($brightness,$saturation ,$hue);} // Adjust brightness, saturation, hue
public function charcoal($radius,$sigma){$this->image->charcoalImage($radius,$sigma);} // Sketch effect
public function oil_paint($radius){$this->image->oilPaintImage($radius);} // Oil painting effect
public function flop(){$this->image-> ;flopImage();} // Horizontal flip
public function flip(){$this->image->flipImage();} // Vertical flip
}
The solution to situation 2 is as follows:
First use the /usr/local/imagemagick/bin/convert -version command to check whether the output content has multi-threading enabled. If the value of Features: is empty, it means it is single-threaded. If the value of Features: is openMP, it means it is. Multi-threading. There is a bug in the multi-thread mode of imagick, which will cause the multi-core CPU usage to surge to 100 instantly, so you must use its single-thread mode.
Copy code The code is as follows:
Version: ImageMagick 6.7.1-2 2014-05-29 Q16 http:// www.imagemagick.org
Copyright: Copyright (C) 1999-2011 ImageMagick Studio LLC
Features:
The above is the result displayed when my configuration is correct. If the configuration is not correct, the result below will be displayed
Copy code The code is as follows:
Version: ImageMagick 6.7.1-2 2014-05-29 Q16 http:// www.imagemagick.org
Copyright: Copyright (C) 1999-2011 ImageMagick Studio LLC
Features: openMP
The first result is single-threaded mode, and the second result is multi-threaded mode. Because the multi-threaded mode of imagick has a bug, so if you first installed imagick in multi-threaded mode, you must yum remove imagemagick Just uninstall it and reinstall it.
After rewriting the class and reinstalling imagick, everything is normal, and the performance of image processing has been greatly improved than before
http://www.bkjia.com/PHPjc/779163.htmlwww.bkjia.comtruehttp: //www.bkjia.com/PHPjc/779163.htmlTechArticleThe GD library is usually used for PHP mapping. Because it is built-in, there is no need to install additional plug-ins on the server, so using It seems more worry-free, but if the main function of your program is to process images, then...