zoukankan      html  css  js  c++  java
  • PHP 使用GD库合成带二维码和圆形头像的海报步骤以及源码实现

    PHP 使用GD库合成带二维码和圆形头像的海报步骤以及源码实现

    之前记录过一篇文章,不过那只是简单将二维码合成到海报中去,这次还要合成头像,而且是圆形。所需要素材就不一一列举,直接代码吧

    1、先获取用户头像

    有的用户是自定义头像(自定义头像是其他站点),有的用户是小程序头像

     1 if (!$user['logo_status'] && $user['logo']) {
     2     $app_domain = config('app_url');//因为自己上传的头像都放在了小程序的后台上
     3     $user['avatarurl'] = $app_domain.$user['logo'];
     4     //$headurl = getcwd().'/upload/logo/30f792c66405eb51304086cec6025b48.png';
     5 }
     6 $img_file = curl_file_get_contents($user['avatarurl']);  //小程序传的头像是网络地址需要周转一下
     7 //$img_content_logo= base64_encode($img_file);
     8 $file_tou_name = time().".png";
     9 $headurl = getcwd().'/upload/logo/'.$file_tou_name;
    10 file_put_contents($headurl,$img_file);

    2、将二维码缩小到206*206,微信二维码默认尺寸是430*430

    1 //1、首先将二维码缩小成206*206
    2 $thumb = imagecreatetruecolor(206,206);     //创建一个新的画布(缩放后的),从左上角开始填充透明背景
    3 $img_content = $this->get_resource_by_img(getcwd().$qrcode);//虽然保存二维码文件的时候,以后缀.png命名,但是格式确实jpg格式的图片
    4 imagecopyresampled($thumb, $img_content, 0, 0, 0, 0, 206, 206, 430, 430);
    5 imagedestroy($img_content);

    3、将二维码合成到海报中,前提海报尺寸为750*909,

    1 //$arr = getimagesize(getcwd().$promote['value']);
    2 //if($arr[2] != 2) com_out_fail('海报资源格式不正确,请联系后台管理员更换');
    3 //$imgs = imagecreatefromjpeg(getcwd().$promote['value']);
    4 $imgs = $this->get_resource_by_img(getcwd().$promote['value']);//暂时海报资源是png格式的
    5 imagecopy($imgs, $thumb, 272, 529, 0, 0, 206, 206);

    4、将头像转换成圆形,再裁剪为132*132,其实小程序头像默认尺寸就是132*132的,这里主要是兼容自定义头像

     1 //将用户头像先转换成圆形,再合成到海报中
     2 list($imgg,$w) = $this->yuan_img($headurl);//yuan_img() 方法在文末会列出
     3 //$file_name = "2_".time().".png";
     4 //imagepng($imgg,getcwd().'/upload/logo/'.$file_name);
     5 //裁剪为132*132的
     6 $imgg = $this->get_new_size($imgg,132,132,$w);//小程序头像其实不用裁剪,小程序头像本身就是132*132的,不过文档好像没更新
     7 //$file_name = "4_".time().".png";
     8 //imagepng($imgg,getcwd().'/upload/logo/'.$file_name);
     9 //imagedestroy($imgg);
    10 //$logo = imagecreatefrompng(getcwd().'/upload/logo/'.$file_name);
    11 imagecopy($imgs, $imgg, 309, 20, 0, 0, 132, 132);

    5、最后保存生成的海报,避免重复生成,只需要在合适的机会重新生成就行

     1 //最后、保存到服务器
     2 $promote_img = '/upload/promote_img/'.$this->id."_promote_img.png";
     3 imagepng($imgs,getcwd().$promote_img); //保存
     4 imagedestroy($imgs);
     5 imagedestroy($thumb);
     6 imagedestroy($imgg);
     7 //删除多余图片文件
     8 unlink($headurl);
     9 //4、入库
    10 User::where('id',$this->id)->update([
    11     'promote_img'=>$promote_img,
    12     'promote_img_status'=>1,
    13 ]);

    用到的方法如下

     1 /*
     2  * 通过curl获取数据,而不是发送请求,比file_get_contents效率高
     3  */
     4 function curl_file_get_contents($durl)
     5 {
     6     $ch = curl_init();
     7     curl_setopt($ch, CURLOPT_URL, $durl);
     8     curl_setopt($ch, CURLOPT_TIMEOUT, 5);
     9     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    10     $r = curl_exec($ch);
    11     curl_close($ch);
    12     return $r;
    13 }
     1     /*
     2      * 转换为圆形
     3      */
     4     private function yuan_img($imgpath)
     5     {
     6         $wh  = getimagesize($imgpath);//pathinfo()不准
     7         $src_img = null;
     8         switch ($wh[2]) {
     9             case 1:
    10                 //gif
    11                 $src_img = imagecreatefromgif($imgpath);
    12                 break;
    13             case 2:
    14                 //jpg
    15                 $src_img = imagecreatefromjpeg($imgpath);
    16                 break;
    17             case 3:
    18                 //png
    19                 $src_img = imagecreatefrompng($imgpath);
    20                 break;
    21         }
    22         $w   = $wh[0];
    23         $h   = $wh[1];
    24         $w   = min($w, $h);
    25         $h   = $w;
    26         $img = imagecreatetruecolor($w, $h);
    27         //这一句一定要有
    28         imagesavealpha($img, true);
    29         //拾取一个完全透明的颜色,最后一个参数127为全透明
    30         $bg = imagecolorallocatealpha($img, 255, 255, 255, 127);
    31         imagefill($img, 0, 0, $bg);
    32         $r   = $w / 2; //圆半径
    33         $y_x = $r; //圆心X坐标
    34         $y_y = $r; //圆心Y坐标
    35         for ($x = 0; $x < $w; $x++) {
    36             for ($y = 0; $y < $h; $y++) {
    37                 $rgbColor = imagecolorat($src_img, $x, $y);
    38                 if (((($x - $r) * ($x - $r) + ($y - $r) * ($y - $r)) < ($r * $r))) {
    39                     imagesetpixel($img, $x, $y, $rgbColor);
    40                 }
    41             }
    42         }
    43         return [$img,$w];
    44     }
    45 
    46     /*
    47      * 根据指定尺寸裁剪目标图片,这里统一转成132*132的
    48      * 注意第一个参数,为了简便,直接传递的是图片资源,如果是绝对地址图片路径,可以加以改造
    49      */
    50     private function get_new_size($imgpath,$new_width,$new_height,$w)
    51     {
    52         $image_p = imagecreatetruecolor($new_width, $new_height);//新画布
    53         $bg = imagecolorallocatealpha($image_p, 255, 255, 255, 127);
    54         imagefill($image_p, 0, 0, $bg);
    55         imagecopyresampled($image_p, $imgpath, 0, 0, 0, 0, $new_width, $new_height, $w, $w);
    56         return $image_p;
    57     }
    58 
    59     /*
    60      * 根据绝对路径的图片地址获取对应的图片资源,
    61      */
    62     private function get_resource_by_img($img)
    63     {
    64         $wh  = getimagesize($img);//比pathinfo要准
    65         $src_img = null;
    66         switch ($wh[2]) {
    67             case 1:
    68                 //gif
    69                 $src_img = imagecreatefromgif($img);
    70                 break;
    71             case 2:
    72                 //jpg
    73                 $src_img = imagecreatefromjpeg($img);
    74                 break;
    75             case 3:
    76                 //png
    77                 $src_img = imagecreatefrompng($img);
    78                 break;
    79         }
    80         return $src_img;
    81     }

    最后来一张,合成的效果图:

  • 相关阅读:
    cyren提供安全规则
    AC自动机——1 Trie树(字典树)介绍
    代码静态分析工具——splint的学习与使用
    Aria2+WebUI,迅雷倒下之后的代替品
    立华科技
    centos平台基于snort、barnyard2以及base的IDS(入侵检测系统)的搭建与测试及所遇问题汇总
    Iperf使用方法与参数说明
    网络基本功(一):细说网络传输
    TCP窗口扩大选项
    TCP Nagle算法&&延迟确认机制
  • 原文地址:https://www.cnblogs.com/cyfblogs/p/10725590.html
Copyright © 2011-2022 走看看