浅談php拡張imgick
PHPの図面は通常GDライブラリを使用しています。内蔵されているので、サーバーにプラグインを追加する必要はないので、使いやすいです。でも、プログラムの主な機能が画像を処理すると、G Dを使用することは勧められません。このため、最近私のプロジェクトをGDからimgickに変えましたが、改善した後、いくつかの状況がありました。ここで皆さんに分かち合います。
まず、こちらの状況を説明します。
状況一:画像操作のクラスを書き換える必要があります。
状況二:imgickマルチスレッドの場合、cpuの使用率は100%まで増加します。
ついでに、イマジックのセンター6.4の設置方法を教えてください。
1、ImageMagickの取り付け
次に、上記の二つの状況についてそれぞれ解決方法を提出します。
状況一の解決方法は以下の通りです。
まず/usr/local/imagmagick/bin/convert-versionコマンドで出力内容が既に開いていますか?Feature:の値が空です。Feature:の値がopenMPならマルチスレッドです。imgickのマルチスレッドモードは一つのbugがあります。彼は多くのコアのスレッドを瞬間的に100%アップします。
classを書き換えて、imgickを装った後は正常で、画像処理の効果は以前より大幅に向上しました。
まず、こちらの状況を説明します。
状況一:画像操作のクラスを書き換える必要があります。
状況二:imgickマルチスレッドの場合、cpuの使用率は100%まで増加します。
ついでに、イマジックのセンター6.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の設置拡大:imgick
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<=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);
}
}
/**
:
$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 a
/**/
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/imagmagick/bin/convert-versionコマンドで出力内容が既に開いていますか?Feature:の値が空です。Feature:の値がopenMPならマルチスレッドです。imgickのマルチスレッドモードは一つのbugがあります。彼は多くのコアのスレッドを瞬間的に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
第一の結果はシングルスレッドモードで、第二の結果はマルチスレッドモードであり、imgickのマルチスレッドモードはバグがあるので、最初はマルチスレッドモードでインストールされたimgickであれば、yum remove imagmagickをアンインストールして再インストールする必要があります。classを書き換えて、imgickを装った後は正常で、画像処理の効果は以前より大幅に向上しました。