最近有一個小任務是生成海報 - 以供用戶分享引流,無奈對GD庫並不熟悉,只得網上找輪子,其中涉及到的問題有:
1、二維碼添加到海報背景圖之中
PHP操作圖片使用GD庫,添加文字以及圖片:
<?php /** * 生成宣傳海報 * @param array 參數,包括圖片和文字 * @param string $filename 生成海報文件名,不傳此參數則不生成文件,直接輸出圖片 * @return [type] [description] */ function createPoster($config=array(),$filename=""){ //如果要看報什么錯,可以先注釋調這個header if(empty($filename)) header("content-type: image/png"); $imageDefault = array( 'left'=>0, 'top'=>0, 'right'=>0, 'bottom'=>0, 'width'=>100, 'height'=>100, 'opacity'=>100 ); $textDefault = array( 'text'=>'', 'left'=>0, 'top'=>0, 'fontSize'=>32, //字號 'fontColor'=>'255,255,255', //字體顏色 'fontPath' => 'arial.ttf', 'angle'=>0, ); $background = $config['background'];//海報最底層得背景 //背景方法 $backgroundInfo = getimagesize($background); $backgroundFun = 'imagecreatefrom'.image_type_to_extension($backgroundInfo[2], false); $background = $backgroundFun($background); $backgroundWidth = imagesx($background); //背景寬度 $backgroundHeight = imagesy($background); //背景高度 $imageRes = imageCreatetruecolor($backgroundWidth,$backgroundHeight); $color = imagecolorallocate($imageRes, 0, 0, 0); imagefill($imageRes, 0, 0, $color); // imageColorTransparent($imageRes, $color); //顏色透明 imagecopyresampled($imageRes,$background,0,0,0,0,imagesx($background),imagesy($background),imagesx($background),imagesy($background)); //處理了圖片 if(!empty($config['image'])){ foreach ($config['image'] as $key => $val) { $val = array_merge($imageDefault,$val); $info = getimagesize($val['url']); $function = 'imagecreatefrom'.image_type_to_extension($info[2], false); if($val['stream']){ //如果傳的是字符串圖像流 $info = getimagesizefromstring($val['url']); $function = 'imagecreatefromstring'; } $res = $function($val['url']); $resWidth = $info[0]; $resHeight = $info[1]; //建立畫板 ,縮放圖片至指定尺寸 $canvas=imagecreatetruecolor($val['width'], $val['height']); imagefill($canvas, 0, 0, $color); //關鍵函數,參數(目標資源,源,目標資源的開始坐標x,y, 源資源的開始坐標x,y,目標資源的寬高w,h,源資源的寬高w,h) imagecopyresampled($canvas, $res, 0, 0, 0, 0, $val['width'], $val['height'],$resWidth,$resHeight); $val['left'] = $val['left']<0?$backgroundWidth- abs($val['left']) - $val['width']:$val['left']; $val['top'] = $val['top']<0?$backgroundHeight- abs($val['top']) - $val['height']:$val['top']; //放置圖像 imagecopymerge($imageRes,$canvas, $val['left'],$val['top'],$val['right'],$val['bottom'],$val['width'],$val['height'],$val['opacity']);//左,上,右,下,寬度,高度,透明度 } } //處理文字 if(!empty($config['text'])){ foreach ($config['text'] as $key => $val) { $val = array_merge($textDefault,$val); list($R,$G,$B) = explode(',', $val['fontColor']); $fontColor = imagecolorallocate($imageRes, $R, $G, $B); $val['left'] = $val['left']<0?$backgroundWidth- abs($val['left']):$val['left']; $val['top'] = $val['top']<0?$backgroundHeight- abs($val['top']):$val['top']; imagettftext($imageRes,$val['fontSize'],$val['angle'],$val['left'],$val['top'],$fontColor,$val['fontPath'],$val['text']); } } //保存到本地 $res = imagejpeg ($imageRes,$filename,90); imagedestroy($imageRes); if(!$res) return false; return $filename; } $config = array( 'image'=>array( array( 'url'=>'qrcode.png', //二維碼資源 'stream'=>0, 'left'=>264, 'top'=>800, 'right'=>0, 'bottom'=>0, 'width'=>225, 'height'=>225, 'opacity'=>100, ), array( 'url'=>'top.jpg', //用戶頭像 'stream'=>0, 'left'=>50, 'top'=>50, 'right'=>0, 'bottom'=>0, 'width'=>100, 'height'=>100, 'opacity'=>100, ), ), 'text'=>array( array( 'text'=> 'rookie', 'left'=> 48, 'top'=>183, 'fontSize'=>22, //字號 'fontColor'=>'255,255,255', //字體顏色 'angle'=>0, 'fontPath'=> __DIR__.'/simsun.ttf',//當前文件下的字體,注意要支持中文哦,否則會亂碼的 ) ), 'background'=>'poster_bg.jpg' //背景圖 ); // 開始生成圖片 createPoster($config,'new.jpg');
2、將微信頭像轉為圓形
<?php /** * 將圖片轉為圓形 * @param [string] $img 原始圖片地址 * @param [string] $save_img 生成后的圓形圖片存儲路徑 * @author xu * @copyright 2018-11-14 */ function circular_img($img,$save_img){ $ext=pathinfo($img); $src_img = null; switch ($ext['extension']) { case 'jpg': $src_img=imagecreatefromjpeg($img); break; case 'png': $src_img=imagecreatefrompng($img); break; } $wh= getimagesize($img); $w=$wh[0]; $h=$wh[1]; $w=min($w,$h); $h= $w; $img = imagecreatetruecolor($w, $h); //這一句一定要有 imagesavealpha($img, true); //拾取一個完全透明的顏色,最后一個參數127為全透明,並可以設定背景色 $bg = imagecolorallocatealpha($img, 255, 255, 255, 127); imagefill($img, 0, 0, $bg); $r = $w / 2; //圓半徑 $y_x = $r; //圓心X坐標 $y_y = $r; //圓心Y坐標 for ($x = 0; $x < $w; $x++) { for ($y = 0; $y < $h; $y++) { $rgbColor = imagecolorat($src_img, $x, $y); if (((($x - $r) * ($x - $r) + ($y - $r) * ($y - $r)) < ($r * $r))) { imagesetpixel($img, $x, $y, $rgbColor); } } } imagejpeg ($img,$save_img,90); imagedestroy($img); return true; } $res = circular_img('old.jpg','new.jpg'); var_dump($res);
3、往微信公眾平台生成的二維碼中間加入公眾號logo
<?php /** * 二維碼內部新增LOGO * @param [string] $QR 二維碼地址 * @param [string] $logo 公眾號logo * @param [string] $save_img 存儲地址 * @return 已訂閱返回true 沒有訂閱返回false */ function createQRLogo($QR,$logo,$save_img) { $errorCorrectionLevel = 'L';//容錯級別 $matrixPointSize = 6;//生成圖片大小 $QR = imagecreatefromstring(file_get_contents($QR)); $logo = imagecreatefromstring(file_get_contents($logo)); $QR_width = imagesx($QR);//二維碼圖片寬度 $QR_height = imagesy($QR);//二維碼圖片高度 $logo_width = imagesx($logo);//logo圖片寬度 $logo_height = imagesy($logo);//logo圖片高度 $logo_qr_width = $QR_width / 5; $scale = $logo_width/$logo_qr_width; $logo_qr_height = $logo_height/$scale; $from_width = ($QR_width - $logo_qr_width) / 2; //重新組合圖片並調整大小 imagecopyresampled($QR, $logo, $from_width, $from_width, 0, 0, $logo_qr_width, $logo_qr_height, $logo_width, $logo_height); //保存圖片 imagejpeg ($QR,$save_img,90); imagedestroy($QR); return true; } createQRLogo('qrcode.png','logo.jpg','new.jpg');
4、遠程下載圖片到本地
/** * 下載遠程文件到本地 * @param [string] $url 文件遠程地址 * @param [string] $file_path 文件本地存儲路徑 * @author xu * @copyright 2018-11-14 */ function download($url, $file_path) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $file = curl_exec($ch); curl_close($ch); $handle = @fopen($file_path, 'a'); fwrite($handle, $file); fclose($handle); } $images = [ 'http://thirdwx.qlogo.cn/mmopen/abc.png', ]; foreach ( $images as $url ) { download($url,'a.jpg'); }
5、PHP啟用gzip輸出 - 有時候輸出的頁面非常大會自動分塊chunked不如壓縮以后傳輸會更快,如果頁面5m采用gzip的話可以變位1m左右
<?php // 將文本gz壓縮后緩存起來輸出 - 靜態化常用 $str = 'abc'; $gz = gzopen ('tmp.gz','w9' ); gzwrite ($gz,$str); gzclose ($gz); header("Content-Encoding: gzip"); header("Vary: Accept-Encoding"); echo file_get_contents('tmp.gz'); die; // 字符串直接壓縮后輸出 $str = 'abc'; $str = gzencode($str,9); header("Content-Encoding: gzip"); header("Vary: Accept-Encoding"); echo $str;
6、PHP提前輸出結果 - 微信服務器在限定時間內未收到響應會重復發送請求 - 生成圖片比較慢的話就要提前輸出空字符串避免微信服務器重試
<?php // 提前輸出 ob_end_clean(); header("Connection: close"); header("HTTP/1.1 200 OK"); // 如果前端要的是json則添加,默認是返回的html/text header("Content-Type: application/json;charset=utf-8"); ob_start(); echo 'hello world.';// 防止微信服務器重復請求 $size = ob_get_length(); header("Content-Length: $size"); ob_end_flush(); flush(); if (function_exists("fastcgi_finish_request")) { fastcgi_finish_request(); } // 在關閉連接后,繼續運行php腳本 ignore_user_abort(true); set_time_limit(0); sleep(100);
