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<=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内產生缩小图

/**/

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

php7 imagick扩展,浅谈php扩展imagick相关推荐

  1. 台式计算机屏幕扩展,浅谈修图电脑配置(台式/显示器篇)

    作者:@ETPHOTOS 来源:@相机笔记电脑是重要的摄影周边附件.伴随高像素.高速连拍.高清视频的发展,摄影也已成为大家更新电脑的重要推动力.昨天说了一些基础概念,今天说一下台式电脑和显示器. 『主 ...

  2. python的unittest測试框架的扩展浅谈

    非常多时候測试框架须要依据測试数据来自己主动生成測试用例脚本,比方接口測试,通过不同參数构建组合去请求接口,然后验证返回结果.假设这样能通过配置excel数据来驱动測试.而不用去写一大堆的測试用例脚本 ...

  3. 计算机在地理测绘领域的应用,浅谈地理信息系统在测绘领域的扩展应用

    摘 要:随着经济的增长,对国民经济各领域发展的先行者――测绘提出了更高.更迫切的要求,而传统意义的测绘方式已经不能满足测绘精度和效率的要求.而地理信息系统(GIS)在测绘领域的广泛应用,大大提高测绘工 ...

  4. 后端语言除了java_浅谈后端语言优缺点

    浅谈后端语言优缺点 兄弟连教育在前不久,回答了一个关于后端语言选型的问题,那么后端语言都有哪些,存在什么样的优缺点?因此兄弟连与大家分享一下心得. 语言优缺点 C/C++ C 语言虽然是非常贴近操作系 ...

  5. 【大话设计模式】——浅谈设计模式基础

    初学设计模式给我最大的感受是:人类真是伟大啊!单单是设计模式的基础课程就让我感受到了强烈的生活气息. 个人感觉<大话设计模式>这本书写的真好.让貌似非常晦涩难懂的设计模式变的生活化.趣味化 ...

  6. 浅谈GCC预编译头技术

    浅谈GCC预编译头技术 文/jorge --谨以此文,悼念我等待MinGW编译时逝去的那些时间. 其 实刚开始编程的时候,我是丝毫不重视编译速度之类的问题的,原因很简单,因为那时我用BASICA.后来 ...

  7. catia三维轴承_浅谈基于CATIA二次开发的单排四点接触球轴承三维设计论文

    浅谈基于CATIA二次开发的单排四点接触球轴承三维设计论文 一.概述 单排四点接触球转盘轴承是一种能够同时承受较大轴向负荷.径向负荷和倾覆力矩等综合载荷,集支承.旋转.传动.固定等多种功能于一身的特殊 ...

  8. php 爬虫去重,浅谈动态爬虫与去重(续)

    作者:Fr1day@0keeTeam 0x00 前言 在 浅谈动态爬虫与去重 中,分享了动态爬虫中触发事件.监控节点变动.URL去重等的实现方法.在接近一年的线上运行与迭代更新过程中,处理了很多bug ...

  9. 浅谈网络游戏的设计——服务器端编程 (3)

    关键词: 网络游戏 构思 策划 创意 竞争机制 竞争系统 本系列文章始终以浅谈二字开头,所以内容简单,不够深入,希望大家谅解. 但是,正如人类的学习过程一样,是一个由浅入深的过程.市面上很多昂贵的图书 ...

最新文章

  1. struts2 中文乱码问题
  2. OpenAI及DeepMind两团队令未来的AI机器更安全
  3. Javascript 类型转换
  4. Navicat mysql 加索引_mysql 索引 (Navicat添加索引)
  5. python语言程序设计王恺答案在哪找_Python语言程序设计
  6. 如何从零开始写一个 web 框架?
  7. WebAPI(part1)--API及DOM
  8. linux 文件列添加字段,如何在linux中加入所需列的文件?
  9. 北师大计算机试题五答案,北京师范大学计算机软件及理论2022考研招生分析、参考书、真题等复习指导解析...
  10. java中map类型_Java中Map类型遍历的两种方式对比
  11. 安笙机器人_张翰新戏搭档徐璐!包贝尔要和辛芷蕾演奇幻电影?
  12. QQ群统一规范与守则
  13. 电动汽车仿真系列-基于动态规划的混合动力汽车能量管理
  14. AngularJs中input uib-typeahead 搜索加自动补全 注意点
  15. 怎么禁用计算机的文件共享,怎么关闭掉电脑共享文件
  16. Golang 从0到1之任务提醒(二)
  17. [转载]this 指向详细解析(箭头函数)
  18. 魔兽按键精灵 V2.0(修正1)
  19. WIN10极限清理 C盘空间
  20. 解决手机连上电脑热点上不了网的问题

热门文章

  1. 等价无穷小的替换条件
  2. 删除jar包中的.class文件保留源码文件.java文件
  3. 【深入了解ADC:模数转换器的工作原理及应用】
  4. 10.【Lucky】
  5. 解读Bytom丨比原链BTM,连接两个世界的无限可能
  6. 另类看设计模式[来自酷壳网]
  7. JavaScript中===的用法/编程语言中等号的理解
  8. 为什么人人都想做电商,网络商城的优势你了解多少?
  9. 巩固剖析并发基础:并发三大特性详解 代码实例分析可见性问题 深入了解JMM模型
  10. android JS动态框架,jsBridge