• 微信公众号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);
  • 相关阅读:
    Objective-C 生成器模式 -- 简单实用和说明
    Objective-C 桥接模式 -- 简单实用和说明
    Objective-C 工厂模式(下) -- 抽象工厂模式
    Objective-C 工厂模式(上) -- 简单工厂模式
    Linux篇---Vi的使用
    【Spark篇】---SparkSQL中自定义UDF和UDAF,开窗函数的应用
    【Spark篇】---SparkStreaming算子操作transform和updateStateByKey
    【Spark篇】---SparkStream初始与应用
    【Spark篇】---SparkSQL on Hive的配置和使用
    【Spark篇】---Spark中Shuffle机制,SparkShuffle和SortShuffle
  • 原文地址:https://www.cnblogs.com/xuweiqiang/p/9956498.html
Copyright © 2020-2023  润新知