A brief discussion on php extension imagick_PHP tutorial
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
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:
/usr/local/imagemagick/bin/convert -version
2. Install PHP extension: 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
Add: extension = "imagick.so"
Restart lnmp
/root/lnmp reload
Next we propose solutions to the above two situations:
The solution to situation 1 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.
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
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

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

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

In this chapter, we will understand the Environment Variables, General Configuration, Database Configuration and Email Configuration in CakePHP.

PHP 8.4 brings several new features, security improvements, and performance improvements with healthy amounts of feature deprecations and removals. This guide explains how to install PHP 8.4 or upgrade to PHP 8.4 on Ubuntu, Debian, or their derivati

To work with date and time in cakephp4, we are going to make use of the available FrozenTime class.

To work on file upload we are going to use the form helper. Here, is an example for file upload.

In this chapter, we are going to learn the following topics related to routing ?

CakePHP is an open-source framework for PHP. It is intended to make developing, deploying and maintaining applications much easier. CakePHP is based on a MVC-like architecture that is both powerful and easy to grasp. Models, Views, and Controllers gu

Visual Studio Code, also known as VS Code, is a free source code editor — or integrated development environment (IDE) — available for all major operating systems. With a large collection of extensions for many programming languages, VS Code can be c

Validator can be created by adding the following two lines in the controller.
