微信小程序生成當文章頁二維碼海報

微信小程序生成當文章頁二維碼海報

我們在使用微信小程序的時候,會發現微信小程序是無法轉發到朋友圈的。這也許是騰訊基于業務生態的考慮沒有開放這個口子。但作為微信小程序的使用者來說就不是那么方便了。有一些很有趣的小程序我們是很希望將它轉發到朋友圈分享給自己的好友看的。

現在,有一種折衷的方法,就是為小程序生成當前頁面的二維碼,將這個二維碼轉發到朋友圈,別人掃碼是可以進入到小程序里的。雖然有一點點別扭,但總算是變相解決了小程序頁面分享到朋友圈的問題。微信可能一直沒有明確支持這種做法,所以,用到這個方法的朋友,在提交小程序審核的時候,可能需要低調一點咯。

下面我們來看看前端(小程序端)代碼的構成:


qrCode: function(options){
    var self = this;
    var pages = getCurrentPages();    //獲取加載的頁面
    var currentPage = pages[pages.length-1];    //獲取當前頁面的對象
    var url = currentPage.route;   //當前頁面url
    var options = currentPage.options;   //如果要獲取url中所帶的參數可以查看options
    var qrurl = 'pages/detail/detail?id='+ options.id; //拼接當前頁面的path地址
    var imgtag = 'prefix_' + options.id; //拼接生成的圖片文件名
    wx.request({
        url: 'xxxxxx', //后端request地址
        method: 'POST', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
        header: {
            'content-type': 'application/x-www-form-urlencoded; charset=UTF-8'
        },
        data: {
            path: qrurl, //A、C類接口使用,冒號之前是這個數值在后端的名稱,冒號之后是這個數值在前端的名稱
            width: 600, //這里可以不設置,在后端設置也可以
            imgname: imgtag, 
            title: '你的title',
        },
        success: function(res) {
            //console.log(qrurl);
            //console.log(imgtag);
            wx.downloadFile({
                url: 'xxxxxx' + imgtag + '.jpg', //這里填寫你服務器上保存海報圖片的目錄網址
                success:function(res){
                    wx.saveImageToPhotosAlbum({
                        filePath: res.tempFilePath,
                        success(result) {
                            //console.log(result)
                            wx.showModal({
                                title: '提示',
                                content: '二維碼海報已保存在手機相冊,請進入手機相冊找到這張海報并分享到微信朋友圈。',
                                showCancel: false,
                                success: function (res) {
                                    if (res.confirm) {
                                        console.log('用戶點擊確定')
                                    }
                                }
                            })
                        }
                    });
                },fail:function(res){
                    console.log(res)
                }
            });
        },
        fail:function(res) {
            //console.log('isFail')
        }
    });
},

代碼里都有注釋,我簡單講一下,實現這個目的需要進行哪幾個步驟:

第一步:獲取當前頁面的 path,為生成頁面二維碼做準備;

第二步:wx.request 對服務器發送 POST 請求,在后端生成二維碼并合成海報;

第三步:wx.downloadFile 下載服務器指定目錄下生成的海報;

第四步:wx.saveImageToPhotosAlbum 將海報保存在手機相冊。

現在,我們來看后端代碼的構成:

首先,還是取得 $access_token,然后調用微信 A 類二維碼接口來獲取當前頁的小程序碼。

http://api.weixin.qq.com/wxa/getwxacode?access_token=$access_token

這里解釋一下微信小程序 A、B、C 三類接口,很多人在這里都被微信的文檔搞得頭暈。

接口 A 小程序碼(太陽碼), 總數 10 萬個(永久有效,掃碼進入 path 對應的動態頁面);

接口 B 小程序碼(太陽碼), 不限制數量(永久有效,將統一打開固定頁面,可根據 scene 跟蹤推廣人員或場景);

接口 C 小程序二維碼(方形碼), 總數 10 萬個(永久有效,掃碼進入 path 對應的動態頁面)。

這里可以很明顯地看出來,B 類碼我們用不到,那是跟蹤某一個固定頁面的多渠道推廣效果的。而 C 類碼是傳統的方形二維碼,如果是在小程序里看的話,是識別不了的。所以,要生成多個頁面的小程序碼,我們只能選擇 A 類接口。

頁面參數通過前端 POST 過來,我們在后端生成二維碼之后,用file_put_contents()函數將其保存在服務器的指定目錄中(如果是 linux 服務器,請確保目錄可寫,并且 www 這個用戶對該目錄有所有權。 命令行: chown -R www /www/你的目錄地址)。

下一步我們需要調用一個類CombineImage.class.php來合成海報,事先我們已經將一張背景圖上傳到服務器了。這個類是做的圖片拼接工作,跟合成還有一點差別,但是原理上大同小異了。

后端處理好之后,回到前端第三步將圖片下載保存即可,我們在前端加了一個 wx.showModal 提示,引導使用者到相冊里找到這張海報圖,并將其分享到朋友圈。

后端 php 代碼 QRCode.php 如下:


<?php  
    require_once 'CombineImage.class.php';
    function httpGet($url) {
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($curl, CURLOPT_TIMEOUT, 500);
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($curl, CURLOPT_URL, $url);
            $res = curl_exec($curl);
            curl_close($curl);
            return $res;
    }
 
 
    function getAccessToken() {
            $AppId = ""; //小程序APPid
            $AppSecret = ""; //小程序APPSecret
            $data = json_decode(file_get_contents("access_token.json"));
            if ($data->expire_time < time()) {
                $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$AppId.'&secret='.$AppSecret;
                $res = json_decode(httpGet($url));
                $access_token = $res->access_token;
                if ($access_token) {
                    $data->expire_time = time() + 7000;
                    $data->access_token = $access_token;
                    $fp = fopen("access_token.json", "w");
                    fwrite($fp, json_encode($data));
                    fclose($fp);
                }
            } else {
                $access_token = $data->access_token;
            }
            return $access_token;
  }
 
 
    function get_content_post($url,$post_data=array(),$header=array()){   
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 跳過證書檢查  
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, true);  // 從證書中檢查SSL加密算法是否存在 
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        curl_setopt($ch, CURLOPT_AUTOREFERER,true);
        $content = curl_exec($ch);
        $info = curl_getinfo($ch,CURLINFO_EFFECTIVE_URL); 
        $code = curl_getinfo($ch,CURLINFO_HTTP_CODE);       
        curl_close($ch);    
        if($code == "200"){
            return $content;
        }else{
            return "錯誤碼:".$code;
        }
    }
 
 
    $ACCESS_TOKEN = getAccessToken($access_token); 
    //接口A小程序碼,總數10萬個(永久有效,掃碼進入path對應的動態頁面)
    $url = 'http://api.weixin.qq.com/wxa/getwxacode?access_token='.$ACCESS_TOKEN;
    //接口B小程序碼,不限制數量(永久有效,將統一打開首頁,可根據scene跟蹤推廣人員或場景)
    //$url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=".$ACCESS_TOKEN; 
    //接口C小程序二維碼,總數10萬個(永久有效,掃碼進入path對應的動態頁面)
    //$url = 'http://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token='.$ACCESS_TOKEN;
    header('content-type:image/png');
    $color = array(  
            "r" => "114",  //這個顏色碼自己到Photoshop里設
            "g" => "188",  //這個顏色碼自己到Photoshop里設
            "b" => "234",  //這個顏色碼自己到Photoshop里設
    );  
    $data = array(
        //$data['scene'] = "scene";//自定義信息,可以填寫諸如識別用戶身份的字段,注意用中文時的情況  
        //$data['page'] = "pages/index/index";//掃碼后對應的path,只能是固定頁面
        'path' => $_POST['path'], //前端傳過來的頁面path
        'width' => intval(600), //設置二維碼尺寸
        'auto_color' => false,
        'line_color' => $color,
    );
    $data = json_encode($data);
 
    $QRCode = get_content_post($url,$data);
    $imgName = $_POST['imgname'];
    $fileName = $imgName.'.png';
     
    //輸出二維碼
    file_put_contents('QRCode/'.$fileName,$QRCode);
 
    //合成海報
    $ci = new CombineImage(array('QRCode/'.$fileName, 'background.png'), 'QRCode/'.$imgName.'.jpg');
    $ci->combine();
    $ci->show();
 
?gt;

圖片合成類 CombineImage.class.php:


<?php
/**
 * 拼接多幅圖片成為一張圖片
 *
 * 參數說明:原圖片為文件路徑數組,目的圖片如果留空,則不保存結果
 *
 * 例子:
 * 
 * $ci = new CombineImage(array("D:/Downloads/1.jpg", "D:/Downloads/2.png"), "D:/Downloads/3.png");
 * $ci->combine();
 * $ci->show();
 * 
 *
 * @author 張榮杰
 * @version 2012.8.9
 */
class CombineImage {
    /**
     * 原圖地址數組
     */
    private $srcImages;
    /**
     * 每張圖片縮放到這個寬度
     */
    private $width;
    /**
     * 每張圖片縮放到這個高度
     */
    private $height;
    /**
     * 拼接模式,可以選擇水平或垂直
     */
    private $mode;
    /**
     * 水平拼接模式常量
     */
    const COMBINE_MODE_HORIZONTAL = "horizontal";
    /**
     * 垂直拼接模式常量
     */
    const COMBINE_MODE_VERTICAL = "vertical";
    /**
     * 目標圖片地址
     */
    private $destImage;
 
    /**
     * 臨時畫布
     */
    private $canvas;
 
    /**
     * 構造函數,傳入原圖地址數組和目標圖片地址
     */
    public function __construct($srcImages = '', $desImage = '',
        $width = 600, $height = 600,
        $mode = self::COMBINE_MODE_VERTICAL) {
        $this->srcImages = $srcImages;
        $this->destImage = $desImage;
        $this->width = $width;
        $this->height = $height;
        $this->mode = $mode;
        $this->canvas = NULL;
    }
 
    public function __destruct() {
        if ($this->canvas != NULL) {
            imagedestroy($this->canvas);
        }
    }
 
    /**
     * 合并圖片
     */
    public function combine() {
        if (empty($this->srcImages)  || $this->width==0 || $this->height==0) {
            return;
        }
        $this->createCanvas();
        for($i=0; $isrcImages); $i++) {
            $srcImage = $this->srcImages[$i];
            $srcImageInfo = getimagesize($srcImage);
            // 如果能夠正確的獲取原圖的基本信息
            if ($srcImageInfo) {
                $srcWidth = $srcImageInfo[0];
                $srcHeight = $srcImageInfo[1];
                $fileType = $srcImageInfo[2];
                if ($fileType == 2) {
                    // 原圖是 jpg 類型
                    $srcImage = imagecreatefromjpeg($srcImage);
                } else if ($fileType == 3) {
                    // 原圖是 png 類型
                    $srcImage = imagecreatefrompng($srcImage);
                } else {
                    // 無法識別的類型
                    continue;
                }
 
                // 計算當前原圖片應該位于畫布的哪個位置
                if ($this->mode == self::COMBINE_MODE_HORIZONTAL) {
                    $destX = $i * $this->width;
                    $desyY = 0;
                } elseif ($this->mode == self::COMBINE_MODE_VERTICAL) {
                    $destX = 0;
                    $desyY = $i * $this->height;
                }
 
                imagecopyresampled($this->canvas, $srcImage, $destX, $desyY,
                            0, 0, $this->width, $this->height, $srcWidth, $srcHeight);
            }
        }
 
        // 如果有指定目標地址,則輸出到文件
        if ( ! empty($this->destImage)) {
            $this->output();
        }
    }
 
    /**
     * 輸出結果到瀏覽器
     */
    public function show() {
        if ($this->canvas == NULL) {
            return;
        }
        header("Content-type: image/jpeg");
        imagejpeg($this->canvas);
    }
 
    /**
     * 私有函數,創建畫布
     */
    private function createCanvas() {
        $totalImage = count($this->srcImages);
        if ($this->mode == self::COMBINE_MODE_HORIZONTAL) {
            $width = $totalImage * $this->width;
            $height = $this->height;
        } else if ($this->mode == self::COMBINE_MODE_VERTICAL) {
            $width = $this->width;
            $height = $totalImage * $this->height;
        }
        $this->canvas = imagecreatetruecolor($width, $height);
 
        // 使畫布透明
        $white = imagecolorallocate($this->canvas, 255, 255, 255);
        imagefill($this->canvas, 0, 0, $white);
        imagecolortransparent($this->canvas, $white);
    }
 
    /**
     * 私有函數,保存結果到文件
     */
    private function output() {
        // 獲取目標文件的后綴
        $fileType = substr(strrchr($this->destImage, '.'), 1);
        if ($fileType=='jpg' || $fileType=='jpeg') {
            imagejpeg($this->canvas, $this->destImage);
        } else {
            // 默認輸出 png 圖片
            imagepng($this->canvas, $this->destImage);
        }
 
    }
 
    /**
     * @return the $srcImages
     */
    public function getSrcImages() {
        return $this->srcImages;
    }
 
    /**
     * @param Array $srcImages
     */
    public function setSrcImages($srcImages) {
        $this->srcImages = $srcImages;
    }
 
    /**
     * @return the $width
     */
    public function getWidth() {
        return $this->width;
    }
 
    /**
     * @param int $width
     */
    public function setWidth($width) {
        $this->width = $width;
    }
 
    /**
     * @return the $height
     */
    public function getHeight() {
        return $this->height;
    }
 
    /**
     * @param int $height
     */
    public function setHeight($height) {
        $this->height = $height;
    }
 
    /**
     * @return the $mode
     */
    public function getMode() {
        return $this->mode;
    }
 
    /**
     * @param const $mode
     */
    public function setMode($mode) {
        $this->mode = $mode;
    }
 
    /**
     * @return the $destImage
     */
    public function getDestImage() {
        return $this->destImage;
    }
 
    /**
     * @param String $destImage
     */
    public function setDestImage($destImage) {
        $this->destImage = $destImage;
    }
}
?>

將這兩個文件保存在服務器某個目錄下,并在同目錄下添加一個 QRCode 子目錄(請確保整個目錄及子目錄都有寫入權限)。然后拿目錄對應的網址分別填寫進前端代碼的對應位置即可。

現在,打開小程序調試工具開始調試吧!

作者:三藏 來源:紅人網絡

相關推薦

微信掃一掃

微信掃一掃

微信掃一掃,分享到朋友圈

微信小程序生成當文章頁二維碼海報
返回頂部

顯示

忘記密碼?

顯示

顯示

獲取驗證碼

Close
七星彩走势图500