浅谈php扩展imagick_PHP教程
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之后一切正常,而且处理图像的效能比之以前有了大幅提升

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

In diesem Kapitel werden wir die Umgebungsvariablen, die allgemeine Konfiguration, die Datenbankkonfiguration und die E-Mail-Konfiguration in CakePHP verstehen.

PHP 8.4 bringt mehrere neue Funktionen, Sicherheitsverbesserungen und Leistungsverbesserungen mit einer beträchtlichen Menge an veralteten und entfernten Funktionen. In dieser Anleitung wird erklärt, wie Sie PHP 8.4 installieren oder auf PHP 8.4 auf Ubuntu, Debian oder deren Derivaten aktualisieren. Obwohl es möglich ist, PHP aus dem Quellcode zu kompilieren, ist die Installation aus einem APT-Repository wie unten erläutert oft schneller und sicherer, da diese Repositorys in Zukunft die neuesten Fehlerbehebungen und Sicherheitsupdates bereitstellen.

Um in cakephp4 mit Datum und Uhrzeit zu arbeiten, verwenden wir die verfügbare FrozenTime-Klasse.

Um am Datei-Upload zu arbeiten, verwenden wir den Formular-Helfer. Hier ist ein Beispiel für den Datei-Upload.

In diesem Kapitel lernen wir die folgenden Themen im Zusammenhang mit dem Routing kennen.

CakePHP ist ein Open-Source-Framework für PHP. Es soll die Entwicklung, Bereitstellung und Wartung von Anwendungen erheblich vereinfachen. CakePHP basiert auf einer MVC-ähnlichen Architektur, die sowohl leistungsstark als auch leicht zu verstehen ist. Modelle, Ansichten und Controller gu

Visual Studio Code, auch bekannt als VS Code, ist ein kostenloser Quellcode-Editor – oder eine integrierte Entwicklungsumgebung (IDE) –, die für alle gängigen Betriebssysteme verfügbar ist. Mit einer großen Sammlung von Erweiterungen für viele Programmiersprachen kann VS Code c

Der Validator kann durch Hinzufügen der folgenden zwei Zeilen im Controller erstellt werden.
