PHP使用imagick扩展实现合并图像的方法


Posted in PHP onApril 25, 2017

本文实例讲述了PHP使用imagick扩展实现合并图像的方法。分享给大家供大家参考,具体如下:

女朋友做外贸的,最近需要做个产品册,要求是每张A4纸上有20个图片,我心想小case吧,哥们会点ps呢。可是当她把图片发给俺,俺一看差点吓屎,近10000张图片,这要ps必定吐血身亡。。。

还好俺还会点php,好吧,写个小程序来完成拼图。因为图片都是按编号排列的,要求给每个图片都加上编号,于是我的思路是:1.先把所有图片缩放到统一尺寸 2.把每张图片和编号组合到一张图 3.把每20张图再组合到一张图。图片处理用到了ImageMagick和php的imagick扩展。下面上代码,有详细注释:

第一步:

// step1: 调整尺寸到 590 x 590
$a = ROOT . '/' . 'a';
// 扫描目录
$dirA = scandir($a);
$im = new Imagick;
foreach ($dirA as $item) {
// 跳过目录和缩略图
if ($item === '.' || $item === '..' || strstr($item, '.db')) {
continue;
}
// 读取图片
$im->readImage($a . '/' . $item);
// 获取图片宽x高
$geo = $im->getImageGeometry();
if ($geo['width'] === 590 && $geo['height'] === 590) {
// 宽高符合,跳过
} else {
// 调整尺寸到590 x 590
im->resizeImage(590, 590, Gmagick::FILTER_UNDEFINED, 1, TRUE);
}
// 将图片保存到另一目录
$im->writeImage(ROOT . '/_a/' . $item);
// 释放资源
$im->destroy();
}

第二步:

// step2: 合并图片和名字
// 扫描目录
$files = scandir(ROOT . '/_a');
$k = 0;
foreach ($files as $item) {
// 跳过目录和缩略图
if ($item === '.' || $item === '..' || strstr($item, '.db')) {
continue;
}
// 文本图片的宽
$twidth = 570;
// 文本图片的高
$theight = 141;
// 获取图片名
$pathinfo = pathinfo($item);
$filename = $pathinfo['filename'];
// 初始化图片对象
$text = new Imagick;
// 初始化绘制对象
$draw = new ImagickDraw;
// 设置字体,这里是放到网站的font下的微软雅黑
$draw->setFont('font/msyh.ttf');
// 文字大小
$draw->setFontSize(40);
// 文字颜色
$draw->setFillColor(new ImagickPixel('#000000'));
// 文字对齐方式
$draw->setTextAlignment(Imagick::ALIGN_LEFT);
// 获取文字信息,主要是长宽,因为要实现在图片居中
$a = $text->queryFontMetrics($draw, $filename);
// 添加文字
$draw->annotation(($twidth - $a['textWidth']) / 2, 80, $filename);
// 建立图像
$text->newImage($twidth, $theight, new ImagickPixel('#ffffff'));
// 图片格式
$text->setImageFormat('png');
// 绘制图片
$text->drawImage($draw);
// 新建一个空白图片用来做画布
$canvas = new Imagick;
$canvas->newimage(570, 661, 'white');
$canvas->setImageFormat('png');
// 读取图片
$pic = new Imagick;
$pic->readImage(ROOT . '/_a/' . $item);
$pic->scaleimage(470, 470, TRUE);
// 将图片合并到画布
$canvas->compositeImage($pic, Imagick::COMPOSITE_OVER, 50, 50);
// 将文字合并到画布
$canvas->compositeimage($text, Imagick::COMPOSITE_OVER, 0, 520);
// 保存图片到另一目录
$canvas->writeimage(ROOT . '/com_a/' . $item);
$k++;
echo "{$k} files proceeded.\n";
}

效果图

PHP使用imagick扩展实现合并图像的方法

第三步:

// step3: 合并每20张到一页
// 扫描目录
$files = scandir(ROOT . '/com_a');
// 给图片分组
$i = $j = 0;
$group = array();
foreach ($files as $item) {
  if ($item === '.' || $item === '..' || strstr($item, '.db')) {
    continue;
  }
  $i++;
  $group[$j][] = $item;
  if ($i % 20 === 0) {
    $j++;
  }
}
$total = count($group);
// 按组拼接图片,A4纸尺寸,4x5的组合方式
foreach ($group as $k => $v) {
  $canvas = new Imagick;
  $canvas->newimage(2480, 3508, 'white');
  $canvas->setimageformat('png');
  $i = $j = 0;
  foreach ($v as $item) {
    $im = new Imagick(ROOT . '/com_a/' . $item);
    // 预留了150的左边距
    $x = 150 + $i * 570;
    // 130的顶边距
    $y = 130 + $j * 661;
    $canvas->compositeimage($im, Imagick::COMPOSITE_OVER, $x, $y);
    // 每4张一行
    if (($i + 1) % 4 === 0) {
      $i = 0;
      $j++;
    } else {
      $i++;
    }
  }
  $canvas->writeimage(ROOT . '/merge_a/' . $k . '.png');
  $c = $k + 1;
  echo "Group {$c}/{$total} done.\n";
}

效果图

PHP使用imagick扩展实现合并图像的方法

PHP 相关文章推荐
PHP产生随机字符串函数
Dec 06 PHP
php中DOMDocument简单用法示例代码(XML创建、添加、删除、修改)
Dec 19 PHP
PHP跨时区(UTC时间)应用解决方案
Jan 11 PHP
php实现邮件发送并带有附件
Jan 24 PHP
php循环创建目录示例分享(php创建多级目录)
Mar 04 PHP
PHP微框架Dispatch简介
Jun 12 PHP
fckeditor上传文件按日期存放及重命名方法
May 22 PHP
php实现网站文件批量压缩下载功能
Oct 28 PHP
深入解析PHP中foreach语句控制数组循环的用法
Nov 30 PHP
Windows2003下php5.4安装配置教程(Apache2.4)
Jun 30 PHP
PHP合并两个或多个数组的方法
Jan 20 PHP
PHP进阶学习之依赖注入与Ioc容器详解
Jun 19 PHP
PHP实现十进制、二进制、八进制和十六进制转换相关函数用法分析
Apr 25 #PHP
php读取XML的常见方法实例总结
Apr 25 #PHP
利用PHP实现一个简单的用户登记表示例
Apr 25 #PHP
PHP中的正则表达式实例详解
Apr 25 #PHP
PHP利用二叉堆实现TopK-算法的方法详解
Apr 24 #PHP
关于PHP定时发送服务的解决办法
Apr 23 #PHP
php读取和保存base64编码的图片内容
Apr 22 #PHP
You might like
PHP date函数参数详解
2006/11/27 PHP
php数组转成json格式的方法
2015/03/09 PHP
javascript &&和||运算法的另类使用技巧
2009/11/28 Javascript
javascript 从if else 到 switch case 再到抽象
2010/07/17 Javascript
Jquery Autocomplete 结合asp.net使用要点
2010/10/29 Javascript
Javascript级联下拉菜单以及AJAX数据验证核心代码
2013/05/10 Javascript
Jquery实现网页跳转或用命令打开指定网页的解决方法
2013/07/09 Javascript
由点击页面其它地方隐藏div所想到的jQuery的delegate
2013/08/29 Javascript
ie下$.getJSON出现问题的解决方法
2014/02/12 Javascript
JavaScript获取页面上被选中文字的方法技巧
2015/03/13 Javascript
JS中frameset框架弹出层实例代码
2016/04/01 Javascript
动态加载js文件简单示例
2016/04/21 Javascript
JS中mouseover和mouseout多次触发问题如何解决
2016/06/06 Javascript
js实现刷新页面后回到记录时滚动条的位置【两种方案可选】
2016/12/12 Javascript
详解js中常规日期格式处理、月历渲染和倒计时函数
2016/12/28 Javascript
jQuery图片查看插件Magnify开发详解
2017/12/25 jQuery
ajax前台后台跨域请求处理方式
2018/02/08 Javascript
js中数组对象去重的两种方法
2019/01/18 Javascript
ES6基础之 Promise 对象用法实例详解
2019/08/22 Javascript
解决layui的table插件无法多层级获取json数据的问题
2019/09/19 Javascript
解决vant-UI库修改样式无效的问题
2020/11/03 Javascript
[06:11]2014DOTA2国际邀请赛 专访团结一心的VG战队
2014/07/21 DOTA
[02:33]2018DOTA2亚洲邀请赛赛前采访——LGD
2018/04/04 DOTA
使用python实现strcmp函数功能示例
2014/03/25 Python
基于python实现简单日历
2018/07/28 Python
Python Django切换MySQL数据库实例详解
2019/07/16 Python
Python实现打包成库供别的模块调用
2020/07/13 Python
python3中TQDM库安装及使用详解
2020/11/18 Python
HTML5 Canvas 实现K线图的示例代码
2019/12/23 HTML / CSS
奥地利购买珠宝和手表网站:ELLA JUWELEN
2019/09/03 全球购物
CSS 还能这样玩?奇思妙想渐变的艺术
2021/04/27 HTML / CSS
vue实现可拖拽的dialog弹框
2021/05/13 Vue.js
python实现简单的井字棋
2021/05/26 Python
Vue鼠标滚轮滚动切换路由效果的实现方法
2021/08/04 Vue.js
vue如何实现关闭对话框后刷新列表
2022/04/08 Vue.js
python开发制作好看的时钟效果
2022/05/02 Python