laravel后端生成微信小程序海报

先答为啥不用 canvas:
1、canvas 兼容性让你调试到怀疑人生;
2、后端生成一次可以复用;
3、因为里面有小程序码,前端生成会暴露 key 和 secret,如果你要后端生成 token 又传给前端,不如直接后端搞完算了
4、我没有可以任意折磨的前端朋友

前端你用啥都可以,只要能接收 json,上效果:

上代码:

<?php

namespace App\Http\Controllers\Api;

use App\Models\Topic;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use Intervention\Image\Facades\Image;
use Illuminate\Support\Facades\Http;

class ShareController extends Controller
{
    public function getWxMiniAppCode(Request $request, Topic $topic)
    {

        $topic = Topic::find($request->topic_id);

        //是否存在目录,不存在就新建一个
        $path = public_path('uploads/topic_share_wxmini_qrcode/' . $topic->id . '/');

        if (!is_dir($path)){

            $mkdir = mkdir(iconv("UTF-8", "GBK", $path),0755,true);

            $invit_path = '/pages/article/article?TopicId=' . $topic->id . '&type=sharewx';

            $uniBg = public_path('/static/qrcode.jpg');

            $uniBgBottom = public_path('/static/qrcode_bottom.jpg');

            $topicImg = $topic->cover;

            //获取二维码
            $miniProgram = \EasyWeChat::miniProgram();

            $data = $miniProgram->app_code->get($invit_path, [
                'width' => '280', //最小就是280,设置再小服务器也不会返回
            ]);

            $empty_code = public_path('uploads/topic_share_wxmini_qrcode/sharecode.png');

            $empty_share = public_path('uploads/topic_share_wxmini_qrcode/share.jpg');

            if ($data instanceof \EasyWeChat\Kernel\Http\StreamResponse) {
                $filename = $data->saveAs(public_path('uploads/topic_share_wxmini_qrcode/' . $topic->id . '/'), 'sharecode.png');
            }

            //获取二维码,并重新缩放正确比例
            $qrImg = public_path('/uploads/topic_share_wxmini_qrcode/' . $topic->id . '/sharecode.png');

            $qrImgResize = Image::make($qrImg);

            $qrImgResize->widen(190);

            //获取主图宽高,并重新缩放正确比例
            $topicImgResize = Image::make($topicImg);

            $topicImgResize->widen(913);

            //开始拼接图片
            $image = Image::canvas(1080, 1622);

            $image->insert($uniBg, 'top-left', 0, 0);

            $image->insert($topicImgResize, 'top-left', 84, 74);

            $image->insert($uniBgBottom, 'top-left', 0, 1103);

            $image->insert($qrImgResize, 'top-left', 264, 1378);

            $text = $topic->title ? $topic->title : $topic->auto_title;

            //如果文字超出19个字符,就截取后拼接换行
            $textLength = Str::length($text);

            //单行文字数量限制
            $textNum = 21;

            if($textLength < $textNum) {

                $image->text($text, 80, 1170, function($font) {
                    $font->file(base_path().'/public/font/msyh.ttf');
                    $font->size(46);
                    $font->color('#333');
                    $font->align('left');
                    $font->valign('top');
                    $font->angle(0);
                });

            } else {

                $image->text(Str::substr($text, 0, $textNum), 80, 1170, function($font) {
                    $font->file(base_path().'/public/font/msyh.ttf');
                    $font->size(46);
                    $font->color('#333');
                    $font->align('left');
                    $font->valign('top');
                    $font->angle(0);
                });

                $image->text(Str::substr($text, $textNum, $textLength <= 18 ? $textLength : 18), 80, 1240, function($font) {
                    $font->file(base_path().'/public/font/msyh.ttf');
                    $font->size(46);
                    $font->color('#333');
                    $font->align('left');
                    $font->valign('top');
                    $font->angle(0);
                });

            }

            $image->save(public_path('uploads/topic_share_wxmini_qrcode/' . $topic->id . '/share.jpg'));

            $res_path = '/uploads/topic_share_wxmini_qrcode/' . $topic->id . '/share.jpg?' . Str::random(10);

            return response()->json(['share_qr' => $res_path]);

        } else {

            $res_path = '/uploads/topic_share_wxmini_qrcode/' . $topic->id . '/share.jpg?' . Str::random(10);

            return response()->json(['share_qr' => $res_path]);
        }

    }
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 2年前 自动加精
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 13

我封装了一个很方便的插件 :smile:

2年前 评论

服务器部署 node,使用 mcanvas 轻松画 canvas, 杠杠的,避开兼容问题

2年前 评论
wongvio (楼主) 2年前
sparkinzy (作者) 2年前

这种前端现成组件不是有嘛,使用很简单,后端生成慢而且浪费服务器

2年前 评论
wongvio (楼主) 2年前

没人用 wkhtmltoimage? 会写 html 就可以生成图片,不需要拼接图片

2年前 评论

前端生成可以节省服务器资源。用户量上来了这种后端生成方式弊端就很大。

2年前 评论

前端生成比较好,后端生成费资源,把压力抛给客户端 :blush:

2年前 评论