一.需求

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

  具体有需求有以下的需求

  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. CSS (层叠样式表)

    层叠样式表(英文全称:Cascading Style Sheets)是一种用来表现HTML(标准通用标记语言的一个应用)或XML(标准通用标记语言的一个子集)等文件样式的计算机语言.CSS不仅可以静态 ...

  2. Replacing Threads with Dispatch Queues

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

  3. 通过offset值的设置使html元素对齐

    今天是我第一次写这个随笔,为了记录我发现的一个jquery的offset的值的问题. 这个offset的值会因为页面标签是否处于隐藏状态而表现出不同的值,隐藏状态时,offset的值是相对于直接父亲的 ...

  4. /etc目录常用配置文件

    /etc/resolv.conf DNS客户端配置文件,逐渐被网卡配置文件所替代 /etc/hosts 本机DNS解析文件,优先级高于DNS服务器 /etc/hostname CentOS 7 主机名 ...

  5. CVPR2016 Paper list

    CVPR2016 Paper list ORAL SESSIONImage Captioning and Question Answering Monday, June 27th, 9:00AM - ...

  6. koji

    fedora koji https://koji.fedoraproject.org/koji/ centos cbs.centos.org/koji/

  7. KD树学习小结

    几个月后的UPD: 学习完下面之后,实战中的总结: 0.比赛中正解就是kdtree的题目很少很少 1.几类优先考虑kdtree的题目: k(维度) >= 3 的题目 二维平面上涉及区间标记的题目 ...

  8. Spring Boot 内嵌容器 Tomcat / Undertow / Jetty 优雅停机实现

    Spring Boot 内嵌容器 Tomcat / Undertow / Jetty 优雅停机实现 Anoyi 精讲JAVA 精讲JAVA 微信号 toooooooozi 功能介绍 讲解java深层次 ...

  9. 【ACM】nyoj_132_最长回文子串_201308151713

    最长回文子串 时间限制:1000 ms  |  内存限制:65535 KB 难度:4   描述 输入一个字符串,求出其中最长的回文子串.子串的含义是:在原串连续出现的字符串片段.回文的含义是:正着看和 ...

  10. Mac OSX:添加host地址

    Mac OSX的hosts文件位于/private/etc/hosts.记得用sudo权限编辑即可.在文件中添加如下内容: xxx.xxx.xxx.xxx (ip地址)     abc.com(你的h ...