一.需求

  最近公司由于有大量的海报要做,而且海报的布局规模都是一样的,只是内容不同,所以老板想我开发一个图片的生成器。可以根据你输入的内容生成海报图片。

  具体有需求有以下的需求

  1.可以根据将每条数据都是独立的

  2.每条数据都必须居中,如果是数据很长的时候还要自动换行

   3.可以将一个二维码生成在海报中,二维码是自己手动上传的

  4.海报的长度是随着内容的大小而变化的

二.分析

  因为目标文件为图片格式的,所以我想到的方法是使用php的gd库来生成图片。所以以上需求我是通过以下方式去解决的。

  需求1解决方法,因为数据是一次性数据的,这是为了方便市场工作这样子设置的。所以我只能通过添加标识符来切割数据

  需求2解决方法,通过设置每行最长宽度来分割每条数据,并计算每天数据的长度,然后计算出文字位置的偏移量,这里提示一下imagettfbbox()函数可以计算文字段落的长度

  需求3解决方法,通过上传文件然后将二维码转化为规定规格的图片,再定位到画布中即可

  需求4解决方法,通过计算数据的行数,标题以及二维码的总高度,然后设置画布的长度

三.实现过程

  ----------------------------------------------html-------------------------------------------------------------------------------------------------------------------------------

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0">
<title>海报自助生成器</title>
<link rel="stylesheet" type="text/css" href="./css/zui.min.css">
<script src="./jquery-3.2.1.min.js"></script>
<style>
p{
text-align: center;
}
form{
width: 90%;
max-width: 500px;
margin: 0 auto;
line-height: 1.8;
}
input.form-control{
border:1px solid #72a197;
outline: none;
}
select.form-control{
border-color:#72a197;
}
select.form-control:focus{
outline: none;
border-color:#72a197;
box-shadow:0 0 0;
}
.radio_space input {
width: 16px;
line-height: 0px;
text-align: initial;
padding: 0;
}
.container{
text-align: center;
width: 100vw;
height: 480px;
overflow: hidden;
margin: 0 auto;
}
.haibao{
width:100vw;
}
.recruit-title{}
.img-uploading{
display:inline-block;
width:100%;
height:60px;
line-height: 60px;
margin-bottom:10px;
border-radius: 3px;
box-sizing: border-box;
border:1px solid #72a197;
position:relative;
text-align: center;
text-decoration: none !important;
}
.img-p{
/* position:absolute;*/
font-size:45px;
height:60px;
width:100%;
font-weight:100;
color:#72a197;
/*left:calc(50% - 30px);*/
text-align:center;
}
.uploading{
width:100%;
height:60px;
opacity:0;
position: absolute;
top: 0px;
}
.create{
border: none !important;
background:#ea6b51;
color:#fff;
text-shadow: none !important;
}
.welfare-title .txta{
margin:10px 0;
width:100%;
height:150px;
border-radius: 8px;
border:1px solid #72a197;
outline: none;
padding:10px;
}
.welfare-title .img-uploading{
border:1px solid #8d6e63;
}
.welfare-title .img-p{
color:#8d6e63;
}
.activity-title .txta{
margin:10px 0;
width:100%;
height:150px;
border-radius: 8px;
border:1px solid #72a197;
outline: none;
padding:10px;
}
.activity-title .img-uploading{
border:1px solid #78909c;
}
.activity-title .img-p{
color:#78909c;
} </style>
<script type="text/javascript">
function changeimg(imgvalue){
document.getElementById('haibao').src = "./template/t"+imgvalue+".jpg";
}
</script>
</head>
<body>
<p></p>
<p>妈妈再也不担心我不会p图了</p> <form action="toImage.php" id= "uploadForm" class="space form-horizontal" method="POST" enctype="multipart/form-data" >
<!-- 手机类型 1为安卓手机 2为苹果手机 -->
<input type="hidden" name="phoneType" id="phoneType">
<div class="main" style="padding-top: 20px;">
<div class="activity-title">
<div class="form-group">
<label class="col-xs-2">标题:</label>
<div class="col-md-6 col-xs-10">
<input class="form-control" name="title" placeholder="" />
</div>
</div>
<textarea class="txta" name="content"></textarea>
<p style="color: red;">请在每条数据后面添加*</p>
<p style="color: red;">同一条数据请不要手动换行*</p> </div>
<a href="#" class="img-uploading">
<i class="img-p" id="symbol">+</i>
<input type="file" name="file" class="uploading">
</a>
<a href="#haibao" class="btn btn-block create" value="生成" onclick="doUpload();">
生成
</a>
</div>
</form> <p style="margin-top: 20px;">请长按保存,不要直接右上角转发</p>
<p id="exp">参考海报</p> <div class="container">
<img id="haibao" class="haibao" src="./template/t1.png"/>
</div>
<script>
$(".uploading").on("change",function(){ if($(".uploading").val() != ""){
$("#symbol").text("二维码已上传");
$("#symbol").css("fontSize","20px");
}
}); function doUpload() {
var formData = new FormData($( "#uploadForm" )[0]);
$.ajax({
url: 'toImage.php' ,
type: 'POST',
data: formData,
async: false,
cache: false,
contentType: false,
processData: false,
success: function (returndata) {
$("#haibao").attr("src",returndata);
$("#exp").hide();
},
error: function (returndata) { }
});
}
</script>
</body>
</html>

下面是php文件信息

<?php /**
* @param int $fontSize 字体大小
* @param resource $ttf 字体文件路径
* @param string $str 字符串
* @param array $data 数据数组容器
* @param int $textWidth 行宽
* @param int $textHeight 行高
* @param int $top 距离顶部距离
*/ function toCenter($fontSize, $ttf, $str, &$data, $textWidth,$textHeight,&$top)
{
$length = mb_strlen($str,"utf-8");
$rowNum = 0;
$count = count($data);
$index = 0;
for($i = 1; $i <= $length ; $i++ )
{
$substr = mb_substr($str , $index , $i-$index,"utf-8");
// var_dump($substr);
$width = getTextInfo($fontSize, $ttf, $substr)['width'];
if($width >= $textWidth && $width <= ($textWidth + $fontSize*2))
{
$index = $i;
$data[$count+$rowNum]['top'] = $top;
$data[$count+$rowNum]['left'] = (1129-$width)/2;
$data[$count+$rowNum]['str'] = $substr;
$data[$count+$rowNum]['fontSize'] = $fontSize;
$rowNum++;
$top += $textHeight;
}
}
if($index!=$length){
$data[$count+$rowNum]['top'] = $top;
$data[$count+$rowNum]['left'] = (1129-$width)/2;
$data[$count+$rowNum]['str'] = $substr;
$data[$count+$rowNum]['fontSize'] = $fontSize;
$rowNum++;
$top += $textHeight;
} return $data; } function getTextInfo($fontSize, $ttf, $str)
{
$data = imagettfbbox($fontSize, 0, $ttf, $str);
$width = $data[2]-$data[0];
$height = $data[1]-$data[7];
return [
'width' => $width,
'height' => $height
];
} /**
* 制作略缩图方法
* @param string $src 文件路径
* @param int $width 生成略缩图的宽度(只设置高度是则为等比例缩放)
* @param int $height 生成略缩图的高度(只设置宽度是则为等比例缩放)
* @param string $filename 生成略缩图图片保存路径
*/
function makeThumb($src, $width = null, $height = null, $filename)
{
$srcData = getimagesize($src);
list($srcWidth, $srcHeight, $srcType) = $srcData;
if (empty($width))
$width = $srcWidth * ($height / $srcHeight);
if (empty($height))
$height = $srcHeight * ($width / $srcWidth);
switch ($srcType) {
case '1':
$imgType = 'gif';
break;
case '2':
$imgType = 'jpeg';
break;
case '3':
$imgType = 'png';
break;
} $imageCreateFun = 'imagecreatefrom'.$imgType;
$srcImg = $imageCreateFun($src);
$destImg = imagecreatetruecolor(intval($width),intval($height));
imagecopyresampled($destImg, $srcImg,0,0,0,0,$width,$height,$srcWidth,$srcHeight); $imagefunc = 'image'.$imgType; $imagefunc($destImg,$filename.'.'.$imgType);
return $filename.'.'.$imgType;
} // // /************************************************处理二维码开始**************************************************************************/
$codePath = '';
$codeImageType = '';
if ((($_FILES["file"]["type"] == "image/jpeg")||($_FILES["file"]["type"] == "image/jpg")||($_FILES["file"]["type"] == "image/png"))&& ($_FILES["file"]["size"] < 2097152))
{
if($_FILES["file"]["error"] > 0)
{
echo "发生错误" . $_FILES["file"]["error"] . ",请找TzSteady<br />";
exit;
}else
{
move_uploaded_file($_FILES["file"]["tmp_name"],"./code/" . date("Ymd").$_FILES["file"]["name"]);
$codePath = "./code/" . date("Ymd").$_FILES["file"]["name"];
$codePath = makeThumb($codePath,300,false,'./code/'.date("YmdHis"));
$codeImageType = $_FILES["file"]["type"];
}
}else
{
echo "<script>
alert('请上传小于2M的jpg/png/jpeg格式的二维码');
</script>";
exit;
}
/******************************************************处理二维码结束********************************************************************/ $data = [];
$titleTop = 300;
$ttf = './ttf/fangzhengqingkebenyuesongjianti.TTF';
$titleData = [];
$title = trim($_POST['title']);
toCenter(65, $ttf, $title, $titleData, 700,100,$titleTop);
$top =400;
$str = trim($_POST['content']);
$charArr = explode("*",$str);
foreach ($charArr as $key => &$value) {
$value = trim($value);
if(empty($value)) continue;
toCenter(30, $ttf, $value, $data, 800,60,$top);
}
$count = count($data);
$fillNum = ceil(($count-3)+6); // /******************************画图开始********************************************/
$headerPath = './template/head.png';
$fillPath = './template/fill1.png';
$footerPath = './template/footer1.png';
$ttf = './ttf/fangzhengqingkebenyuesongjianti.TTF';
$header = imagecreatefrompng($headerPath);
$fill = imagecreatefrompng($fillPath);
$footer = imagecreatefrompng($footerPath);
switch ($codeImageType) {
case 'image/jpeg':
$code = imagecreatefromjpeg($codePath);
break;
case 'image/jpg':
$code = imagecreatefromjpeg($codePath);
break;
case 'image/png':
$code = imagecreatefrompng($codePath);
if(empty($code))
{
$code = imagecreatefromjpeg($codePath);
}
break;
} list($headerWidth,$headerHeight,$headerType) = getimagesize($headerPath);
list($fillWidth,$fillHeight,$fillType) = getimagesize($fillPath);
list($footerWidth,$footerHeight,$footerType) = getimagesize($footerPath);
list($codeWidth,$codeHeight,$codeType) = getimagesize($codePath);
$img = imagecreatetruecolor($headerWidth,$headerHeight+$fillHeight*$fillNum+$footerHeight); $result = imagecopy($img , $header,0,0,0,0,$headerWidth,$headerHeight);
for($i = 0; $i < $fillNum ; $i++)
{
$result = imagecopy($img , $fill,0,$headerHeight+$fillHeight*$i,0,0,$fillWidth,$fillHeight);
}
$result = imagecopy($img , $footer,0,$headerHeight+$fillHeight*$fillNum,0,0,$footerWidth,$footerHeight); $result = imagecopy($img , $code,420,$fillHeight*($fillNum-1)+$headerHeight-30,0,0,$codeWidth,$codeHeight);
$orange = ImageColorAllocate($img, 249,135,0);
$white = ImageColorAllocate($img, 0,0,0);
$titlered = ImageColorAllocate($img, 163,0,14); if(isset($titleData) && !empty($titleData))
{
foreach ($titleData as $key => &$value) {
imagettftext($img, $value['fontSize'], 0, $value['left'], $value['top'] , $titlered, $ttf,$value['str']);
}
} foreach ($data as $key => &$value) {
imagettftext($img, $value['fontSize'], 0, $value['left'], $value['top'] , $white, $ttf,$value['str']);
}
imagettftext($img, 25, 0, 320 ,$headerHeight+$fillHeight*($fillNum-1)-50, $titlered, $ttf,'有兴趣的同学可以加微信咨询');
$filename = './img/'.date("Ymd-H-i-s").'.png';
imagepng($img,$filename);
echo $filename; // /****************************画图结束**********************************************/

php 图片生成器的更多相关文章

  1. placehold.it-在线图片生成器(转载)

    做网站的时候 如果 有的产品等客户没有上传图片,可以用这个网站生成的图片 并配以文字进行图片的占位 以免造成页面的空挡或者页面错位等 原文地址:http://www.cnblogs.com/xumen ...

  2. placehold.it-在线图片生成器

    placehold的介绍 当我们进行网页设计时,经常会使用各种尺寸的图片.有时候我们用一个固定宽和高的div来进行代替,可是这样的效果不是很明显,而且还要进行各种各样的文字说明:或者我们得从网上寻找各 ...

  3. Loader Generator---loading图片生成器

    if(公司配有专业的设计师) return; Recommend("http://loadergenerator.com/");

  4. js 生成二维码图片

    1.用纯JavaScript实现的微信二维码图片生成器 QRCode.js是javascript实现二维码(QRCode)制作生成库. QRCode.js有着良好的跨浏览器兼容性(高版本使用HTML5 ...

  5. JavaScript资源大全中文版(Awesome最新版--转载自张果老师博客)

    JavaScript资源大全中文版(Awesome最新版)   目录 前端MVC 框架和库 包管理器 加载器 打包工具 测试框架 框架 断言 覆盖率 运行器 QA 工具 基于 Node 的 CMS 框 ...

  6. JavaScript资源大全

    目录 前端MVC 框架和库 包管理器 加载器 打包工具 测试框架 框架 断言 覆盖率 运行器 QA 工具 基于 Node 的 CMS 框架 模板引擎 数据可视化 编辑器 UI 输入 日历 选择 文件上 ...

  7. iOS视频录制、压缩导出、取帧

    概述 花了点时间研究了一下常用的视频获取.录制.压缩.取帧图功能,分享给大家了!相信阅读完本篇文章,会对你有很大的帮助的! 本篇文章研究几下以个功能: 视频录制 从相册选择视频 保持视频到相册 获取视 ...

  8. maven小项目注册服务(二)--captcha模块

    验证码生成模块,配置信息基本和前面的模块一样.account-captcha需要提供的服务是生成随机的验证码主键,然后用户可以使用这个主键要求服务生成一个验证码图片,这个图片对应的值应该是随机的,最后 ...

  9. Awesome Javascript(中文翻译版)

    [导读]:GitHub 上有一个 Awesome – XXX 系列的资源整理.awesome-javascript 是 sorrycc 发起维护的 JS 资源列表,内容包括:包管理器.加载器.测试框架 ...

随机推荐

  1. (转) SolrCloud之分布式索引及与Zookeeper的集成

    http://blog.csdn.net/ebay/article/details/46549481 作者:Wang, Josh 一.概述 Lucene是一个Java语言编写的利用倒排原理实现的文本检 ...

  2. Replacing Threads with Dispatch Queues

    Replacing Threads with Dispatch Queues To understand how you might replace threads with dispatch que ...

  3. 浏览器的 local storage

    浏览器 local storage      本地存储 session storage    会话存储 cookies                  本地存储 1.     local stora ...

  4. Mock随机生成数据模拟后台接口

    <html> <head> <title>测试</title> <script src="http://code.jquery.com/ ...

  5. chrome浏览器处理本地Ajax跨域

    chrome浏览器下 项目开发过程中,用到了Ajax异步请求.若将项目放在本地服务器中,通过localhost访问文件,不会报错.若直接通过file://访问文件就会报错. 报错信息: XMLHttp ...

  6. python 单元测试中处理用例失败的情况

    今天有一个需求, 在单元测试失败的时候打印一些日志, 我们管他叫 dosomething 吧 ,反正就是做一些操作 查了下并没有查到相关的方法, 于是研究了一波unittest 的源码 发现了这个东西 ...

  7. PHP websocket之聊天室实现

    PHP部分 <?php error_reporting(E_ALL); set_time_limit(0);// 设置超时时间为无限,防止超时 date_default_timezone_set ...

  8. unigui的session【1】

    目前是1394. 明白session如何使用管理,看demo Session List和SessionTimeout unit Main; interface uses Windows, Messag ...

  9. scp相关命令总结

    scp 跨机远程拷贝scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的.当你服务器硬盘 ...

  10. GeoTrust 企业(OV)型 多域名(SAN/UC)版

     GeoTrust 企业(OV)型 多域名(SAN/UC)版 SSL证书(GeoTrust True BusinessID With Multi-Domain(SAN/UC) ),支持多域名,属于企业 ...