PHP 使用 Imagick 裁切/生成缩略图/添加水印自动检测和处理 GIF


Posted in PHP onFebruary 19, 2016

给骨头系统开发的图像库的 imagick 部分 ,支持 gif , 完美支持裁切、生成缩略图、添加水印 。

支持按方位生成缩略图像, 如:

// 把左上角优先
$image->resize_to(100, 100, 'north_west');
// 右边优先
$image->resize_to(100, 100, 'east');
...

更多参数看源代码

原图

PHP 使用 Imagick 裁切/生成缩略图/添加水印自动检测和处理 GIF

效果图:

PHP 使用 Imagick 裁切/生成缩略图/添加水印自动检测和处理 GIFPHP 使用 Imagick 裁切/生成缩略图/添加水印自动检测和处理 GIFPHP 使用 Imagick 裁切/生成缩略图/添加水印自动检测和处理 GIF

调用方式:

include 'imagick.class.php'; 
$image = new lib_image_imagick(); 
$image->open('a.gif'); 
$image->resize_to(100, 100, 'scale_fill'); 
$image->add_text('1024i.com', 10, 20); 
$image->add_watermark('1024i.gif', 10, 50); 
$image->save_to('x.gif');

imagick.class.php

<?php 
/* 
@版本日期: 版本日期: 2012年1月18日 
@著作权所有: 1024 intelligence ( http://www.1024i.com ) 
获得使用本类库的许可, 您必须保留著作权声明信息. 
报告漏洞,意见或建议, 请联系 Lou Barnes(iua1024@gmail.com) 
*/ 

class lib_image_imagick 
{ 
private $image = null; 
private $type = null; 
// 构造函数 
public function __construct(){} 

// 析构函数 
public function __destruct() 
{ 
if($this->image!==null) $this->image->destroy(); 
} 
// 载入图像 
public function open($path) 
{ 
$this->image = new Imagick( $path ); 
if($this->image) 
{ 
$this->type = strtolower($this->image->getImageFormat()); 
} 
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); 
} 
} 
/* 
* 更改图像大小 
$fit: 适应大小方式 
'force': 把图片强制变形成 $width X $height 大小 
'scale': 按比例在安全框 $width X $height 内缩放图片, 输出缩放后图像大小 不完全等于 $width X $height 
'scale_fill': 按比例在安全框 $width X $height 内缩放图片,安全框内没有像素的地方填充色, 使用此参数时可设置背景填充色 $bg_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; 
} 
} 


// 添加水印图片 
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); 
} 
} 

// 添加水印文字 
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); 
} 
} 

// 保存到指定路径 
public function save_to( $path ) 
{ 
if($this->type=='gif') 
{ 
$this->image->writeImages($path, true); 
} 
else 
{ 
$this->image->writeImage($path); 
} 
} 
// 输出图像 
public function output($header = true) 
{ 
if($header) header('Content-type: '.$this->type); 
echo $this->image->getImagesBlob(); 
} 

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 is_image() 
{ 
if( $this->image ) 
return true; 
else 
return false; 
} 

public function thumbnail($width = 100, $height = 100, $fit = true){ $this->image->thumbnailImage( $width, $height, $fit );} // 生成缩略图 $fit为真时将保持比例并在安全框 $width X $height 内生成缩略图片 
/* 
添加一个边框 
$width: 左右边框宽度 
$height: 上下边框宽度 
$color: 颜色: RGB 颜色 'rgb(255,0,0)' 或 16进制颜色 '#FF0000' 或颜色单词 'white'/'red'... 
*/ 
public function border($width, $height, $color='rgb(220, 220, 220)') 
{ 
$color=new ImagickPixel(); 
$color->setColor($color); 
$this->image->borderImage($color, $width, $height); 
} 
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();} // 垂直翻转 
}
PHP 相关文章推荐
如何使用PHP获取网络上文件
Oct 09 PHP
让你同时上传 1000 个文件 (二)
Oct 09 PHP
php中的数组操作函数整理
Aug 18 PHP
php 常用类整理
Dec 23 PHP
php防攻击代码升级版
Dec 29 PHP
从零开始学YII2框架(二)通过 Composer 安装扩展插件
Aug 20 PHP
PHP中的日期加减方法示例
Aug 21 PHP
Zend Framework教程之响应对象的封装Zend_Controller_Response实例详解
Mar 07 PHP
Yii框架用户登录session丢失问题解决方法
Jan 07 PHP
PHP实现双链表删除与插入节点的方法示例
Nov 11 PHP
TP5(thinkPHP5)框架使用ajax实现与后台数据交互的方法小结
Feb 10 PHP
通过PHP的Wrapper无缝迁移原有项目到新服务的实现方法
Apr 02 PHP
PHP利用imagick生成组合缩略图
Feb 19 #PHP
对比分析php中Cookie与Session的异同
Feb 19 #PHP
php强大的时间转换函数strtotime
Feb 18 #PHP
php实现中文转数字
Feb 18 #PHP
PHP和MySql中32位和64位的整形范围是多少
Feb 18 #PHP
php脚本运行时的超时机制详解
Feb 17 #PHP
PHP邮件群发机实现代码
Feb 16 #PHP
You might like
php下拉选项的批量操作的实现代码
2013/10/14 PHP
php获取英文姓名首字母的方法
2015/07/13 PHP
thinkphp框架实现数据添加和显示功能
2016/06/29 PHP
微信公众平台开发教程③ PHP实现微信公众号支付功能图文详解
2019/04/10 PHP
php下的原生ajax请求用法实例分析
2020/02/28 PHP
XmlUtils JS操作XML工具类
2009/10/01 Javascript
Javascript Cookie读写删除操作的函数
2010/03/02 Javascript
Textbox控件注册回车事件及触发按钮提交事件具体实现
2013/03/04 Javascript
jquery form表单序列化为对象的示例代码
2014/03/05 Javascript
详解使用Vue.Js结合Jquery Ajax加载数据的两种方式
2017/01/10 Javascript
如何编写jquery插件
2017/03/29 jQuery
Vue.js实战之通过监听滚动事件实现动态锚点
2017/04/04 Javascript
Iscrool下拉刷新功能实现方法(推荐)
2017/06/26 Javascript
React Native 搭建开发环境的方法步骤
2017/10/30 Javascript
微信小程序实现点击按钮修改文字大小功能【附demo源码下载】
2017/12/06 Javascript
使用Angular CLI进行单元测试和E2E测试的方法
2018/03/24 Javascript
Vuex持久化插件(vuex-persistedstate)解决刷新数据消失的问题
2019/04/16 Javascript
node.js实现简单的压缩/解压缩功能示例
2019/11/05 Javascript
纯JS实现五子棋游戏
2020/05/28 Javascript
vue实现点击出现操作弹出框的示例
2020/11/05 Javascript
arcgis.js控制地图地体的显示范围超出区域自动弹回(实现思路)
2021/01/28 Javascript
[02:52]2014DOTA2西雅图国际邀请赛 CIS战队巡礼
2014/07/07 DOTA
Python松散正则表达式用法分析
2016/04/29 Python
Django2.1.3 中间件使用详解
2018/11/26 Python
在Pycharm中使用GitHub的方法步骤
2019/06/13 Python
pyqt 实现为长内容添加滑轮 scrollArea
2019/06/19 Python
python针对mysql数据库的连接、查询、更新、删除操作示例
2019/09/11 Python
python如何判断IP地址合法性
2020/04/05 Python
Python中socket网络通信是干嘛的
2020/05/27 Python
详解基于Facecognition+Opencv快速搭建人脸识别及跟踪应用
2021/01/21 Python
CSS3实现时间轴特效
2020/11/02 HTML / CSS
党员四风问题对照检查材料
2014/09/27 职场文书
师德承诺书
2015/01/20 职场文书
2015年党建工作总结
2015/03/30 职场文书
田径运动会广播稿
2015/08/19 职场文书
对讲机的最大通讯距离是多少
2022/02/18 无线电