微信公眾號PHP生成二維碼海報的幾個小擴展


最近有一個小任務是生成海報 - 以供用戶分享引流,無奈對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);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM