php 图片生成器

一.需求

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

  具体有需求有以下的需求

  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;




// /****************************画图结束**********************************************/

 

posted @ 2018-01-03 11:00  BboyTzsteady  阅读(1951)  评论(0编辑  收藏  举报