Talk about the php extension imagick. PHP graph creation usually uses the GD library, because it is built-in and does not need to install additional plug-ins on the server, it is easy to use, but if your program's main function is to process images, therefore, the GD Library is usually used for PHP graph creation, because it is a built-in plug-in that does not need to be installed on the server, so it is easy to use, however, if the main function of your program is to process images, you are not recommended to use GD because GD is not only inefficient but also weak in ability, and there are a lot of system resources used by compaction, in addition, the creatfrom of GD also has a bug, while imagick is a good alternative. so recently, I changed one of my projects from GD to imagick, however, some situations have emerged after the change.
First, let's talk about my situation:
Condition 1: The Image operation class needs to be rewritten.
Condition 2: the cpu usage increases to 100% when imagick is multithreading.
By the way, the installation method of imagick in centos6.4 is as follows:
1. install ImageMagick
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 can run normally:
The code is as follows:
/Usr/local/imagemagick/bin/convert-version
2. install the PHP extension: imagick
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
The code is as follows:
/Root/lnmp reload
Next, we will propose solutions to the above two situations:
Solution 1:
The code is as follows:
/**
Imagick Image processing
Usage:
// Introduce the Imagick object
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;
// Construct
Public function _ construct (){}
// Structure
Public function _ destruct (){
If ($ this-> image! = Null) {$ this-> image-> destroy ();}
}
// Load the image
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 Image size
Parameters:
$ Width: New width
$ Height: new height
$ Fit: Adaptive size
'Force': force the image to $ width X $ height.
'Scale': scales the image proportionally within $ width X $ height. The result is not completely equal to $ width X $ height.
'Scale _ fill': scales the image in the range of $ width X $ height, and colors are filled with no pixels. $ fill_color = array (255,255,255) (red, green, blue, transparency [0 opacity-127 full transparency])
Others: in smart mode, scale the image and crop the size of $ width X $ height from the center.
Note:
$ Fit = 'force', 'scale', and 'scale _ fill'
$ Fit = output the image at the specified position when the image orientation
The correspondence between letters and images is as follows:
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;
}
}
/**
Add image watermark
Parameters:
$ Path: watermark image (including the complete path)
$ X, $ y: watermark coordinate
/**/
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 coordinate
/**/
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 Archiving
Parameters:
$ Path: the location of the archive and the new archive 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 ();
// Compress if the png background is not transparent
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;
}
}
// Directly output the image to the screen
Public function output ($ header = true ){
If ($ header) header ('content-type: '. $ this-> type );
Echo $ this-> image-> getImagesBlob ();
}
/**
Create a zoom chart
When $ fit is true, the ratio is maintained and the scaled-down graph is generated within $ width X $ height.
/**/
Public function thumbnail ($ width = 100, $ height = 100, $ fit = true) {$ this-> image-> thumbnailImage ($ width, $ height, $ fit );}
/**
Add borders to images
$ Width: Border width
$ Height: Border width
$ Color: dark color
/**/
Public function border ($ width, $ height, $ color = 'rgb (220,220,220 )'){
$ Color = new ImagickPixel ();
$ Color-> setColor ($ color );
$ This-> image-> borderImage ($ color, $ width, $ height );
}
// Obtain the image width
Public function get_width () {$ size = $ this-> image-> getImagePage (); return $ size ['width'];}
// Obtain the image height
Public function get_height () {$ size = $ this-> image-> getImagePage (); return $ size ['height'];}
// Set the image type
Public function set_type ($ type = 'PNG ') {$ this-> type = $ type; $ this-> image-> setImageFormat ($ type );}
// Obtain the image type
Public function get_type () {return $ this-> type ;}
Public function blur ($ radius, $ sigma) {$ this-> image-> blurImage ($ radius, $ sigma);} // blur
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 the brightness, saturation, tone
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 ();} // flip horizontally
Public function flip () {$ this-> image-> flipImage ();} // Vertical flip
}
Solution 2:
First, run the/usr/local/imagemagick/bin/convert-version command to check whether multiple threads have been enabled for the output content. if the value of Features: is null, it indicates a single thread. If Features: the value is openMP, indicating multithreading. there is a bug in the multi-thread mode of imagick, which causes the cpu usage of multiple cores to instantly increase to 100, so you must use its single-thread mode.
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 I configured it correctly. If no configuration is correct, the following result is displayed.
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 the single-thread mode, and the second result is the multi-thread mode, because the multi-thread mode of imagick has bugs, therefore, if you have installed imagick in multi-threaded mode at the beginning, you must uninstall imagemagick and reinstall it.
After the class is rewritten and imagick is reinstalled, everything is normal, and the image processing efficiency is significantly improved compared with the previous one.
...