一.需求javascript
最近公司因爲有大量的海報要作,並且海報的佈局規模都是同樣的,只是內容不一樣,因此老闆想我開發一個圖片的生成器。能夠根據你輸入的內容生成海報圖片。php
具體有需求有如下的需求css
1.能夠根據將每條數據都是獨立的html
2.每條數據都必須居中,若是是數據很長的時候還要自動換行java
3.能夠將一個二維碼生成在海報中,二維碼是本身手動上傳的jquery
4.海報的長度是隨着內容的大小而變化的ajax
二.分析數組
由於目標文件爲圖片格式的,因此我想到的方法是使用php的gd庫來生成圖片。因此以上需求我是經過如下方式去解決的。微信
需求1解決方法,由於數據是一次性數據的,這是爲了方便市場工做這樣子設置的。因此我只能經過添加標識符來切割數據async
需求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; // /****************************畫圖結束**********************************************/