做了一个可以为小程序生成朋友圈分享图片的服务 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
Croath
V2EX    分享创造

做了一个可以为小程序生成朋友圈分享图片的服务

  •  8
     
  •   Croath 2019-10-25 13:47:27 +08:00 9313 次点击
    这是一个创建于 2228 天前的主题,其中的信息可能已经有所发展或是发生改变。

    上一篇图挂了,用 V2EX 图床重新发一个。

    我们最近开发了一些小程序,每次要上线之前都想快速添加到分享朋友圈功能,但是做了几次之后发现好麻烦啊,要么效果不好,要么成本高,要么不能动态更新,所以顺手做了这个解决方案出来,大家有什么问题或者想讨论的可以一起讨论:)欢迎建议:)以下正文:


    小程序生成图片分享朋友圈

    小程序开发者都希望自己的小程序得以广泛传播,因为不少小程序都设计了很多转发激励行为,但分享小程序到朋友圈(或其他外部平台)一直是一个难题。一个常见的方案就是生成分享海报、分享图片。但生成分享图片在技术上却也是一个难题。


    技术选型

    目前常用技术方案基本分为三种:

    1. 使用 canvas 绘图并生成
    2. 使用后端绘图库进行绘制,返回给小程序端
    3. 使用服务端开一个浏览器进行 HTML 渲染,并截图返回给小程序端

    第一种方案:要求较高,canvas 和纯 html 布局相去甚远,零基础学习成本较高,而且在不同的微信浏览器中效果不可预期,想短时间内做出精美可控的生成图片不容易。实操的时候发现了一个非常麻烦的事情:网络图片或者 base64 图片都无法直接在 canvas 里渲染显示,要先下载好传进去。

    第二种方案:后端库可以完成较为简单的需求,但字体加载、阴影、圆角、透明等方案效果需要精调,如果文字需要截断或动态伸缩长度时并不容易处理。图片的截取和伸缩自适应也不灵活。而且选用这种方案相当于需要把 UI 布局的工作丢给后端工程师去解决,这不是他们擅长的范围,效果未必会好。

    第三种方案:页面的绘制方面,纯前端技术即可完成,难度低,完成度高,但是需要在后端起一个 node 服务开启 puppeteer 去控制服务端 Chrome 浏览器。这种方案的缺点就是成本太高,我们和业界同行都测算过,结果差不多:4 核 16G 的服务器生成图片的 QPS 大概只有 10-20,相当于一秒钟较差情况只能生成 10 张图片,这对于突发的大量分享需求并不能满足,而且这种配置的服务器,不能部署其他服务,只跑这个服务就会用尽大部分资源。

    费用上:只单单算 5M 带宽的服务器费用一个月就要 700+ 人民币,流量和图片托管费用另算。此方案的最小化实现:至少需要 1 核 2G 的服务器才能较为顺畅地完成一次顺利截图,但是还是要处理浏览器无响应假死等情况,较为复杂。但综合来看,这种方案是效果最好最为灵活的。

    快海报小程序分享图生成服务

    快海报 kuaihaibao.com 是专门提供小程序分享海报生成服务的,技术上用的就是上面所述的第三种方案,但是只需要调用他的 API 就可以完成,不需要开发者维护 puppeteer 和 headless Chrome,而且成本较低,一张分享图的最低生成成本是 0.033 元。

    其实真正集成到自己的服务中时,平均成本要比这个低,因为有些生成的图片的二维码,如果不带用户个人信息(不给分享的用户返利)时,可以生成一次之后永久缓存起来,其他用户再分享同一个东西都用缓存好的图片,综合成本就降下来了。

    算一下成本:

    • 比方说一个刚起步的小程序日活 5000 (对于刚起步的小程序其实已经很高了吧)
    • 假设有 5% 的用户生成分享图
    • 也就是每天生成 250 张分享图,一个月会生成 7500 张分享图

    这样的话每个月成本就是 250 元人民币左右,相比 700+ 人民币的服务器成本省太多了。这是测算比较高的指标,而且是完全不应用缓存方案的情况。

    如果你的小程序还处于冷启动的阶段:

    • 日活 500
    • 假设有 5% 的用户生成分享图
    • 也就是每天生成 25 张分享图,一个月会生成 750 张分享图

    每月成本 25 元。比 1 核 2G 的最小化自部署方案也要便宜。但带来的收益是无穷的,750 张分享图发到朋友圈,每张分享图 1000 受众浏览,一个月就是将近 750000 人次分享受众。

    调用 API

    首先去 https://kuaihaibao.com/ 注册账号,验证邮箱激活之后,其实就可以先测试用了,每个账号有 100 次测试额度,测试生成的图片带水印。

    网站左侧的 [文档] 页面能找到集成文档,非常简单,一共就只有一个核心 API,通过 HTTP 调用的。

    先在 [开发] -> [设置] 中激活 token

    激活 token

    目前支持三种生成方式:

    1. 直接传 URL 进行渲染
    2. 传 HTML 渲染
    3. 使用内置的模板进行选择

    这里演示使用模板渲染,因为比较简单

    打开 [开发] -> [模板] 中,找到自己喜欢的模版。因为我只想生成一个简单的分享图片,所以最简单的方式就是使用网站内置的模版,内置模板目前有 8 款,应该能满足大部分小程序的需求了,抽奖、打卡、图文、文字、电商都有,改一改文案和图片就可以了。

    我选了这个抽奖模板:

    抽奖模板

    按照 https://kuaihaibao.com/doc/docs/template/kzccda95.html 文档描述的 JSON 改成我需要的:

    { "backgroundColor": "#fafafa", "backgroundImage": "", "user": { "avatar": "https://khb-sample.oss-cn-shanghai.aliyuncs.com/sample/girl_2.jpg", "nickname": "我是测试账号", "color": "#666" }, "tip": "邀请你来抽奖", "qrcode": "https://khb-sample.oss-cn-shanghai.aliyuncs.com/sample/sample_qr_0.png", "records": [ { "title": "一等奖", "desc": "2019 年 11 月 16 日 10:00 开奖", "image": "https://s3.cn-northwest-1.amazonaws.com.cn/res.weiyidan.com/production/10000002/4109f8e51a8f43b9816dbc8fe636e22a.jpeg" } ], "brand": "我的测试抽奖小程序", "slogan": "快来和我一起抽吧!", "metaColor": "#999" } 

    然后打开 Terminal 做一次请求试试:

    curl -X "POST" "https://api.kuaihaibao.com/services/screenshot" \ -H 'Authorization: Bearer 这里写你自己的 token' \ -H 'Content-Type: application/json; charset=' \ -d /pre>{ "template": "kzccda95", "data": { "qrcode": "https://khb-sample.oss-cn-shanghai.aliyuncs.com/sample/sample_qr_0.png", "records": [ { "title": "一等奖", "desc": "2019 年 11 月 16 日 10:00 开奖", "image": "https://s3.cn-northwest-1.amazonaws.com.cn/res.weiyidan.com/production/10000002/4109f8e51a8f43b9816dbc8fe636e22a.jpeg" } ], "tip": "邀请你来抽奖", "slogan": "快来和我一起抽吧!", "metaColor": "#999", "brand": "我的测试抽奖小程序", "backgroundImage": "", "backgroundColor": "#fafafa", "user": { "avatar": "https://khb-sample.oss-cn-shanghai.aliyuncs.com/sample/girl_2.jpg", "nickname": "我是测试账号", "color": "#666" } } }' 

    返回了结果:

    { "success": true, "data": { "name": "iPhone 5", "image": "https://khb-test-oss.oss-cn-shanghai.aliyuncs.com/screenshot/4fa63f2a3605cbdece90c659cbccea619d9cf9fa?x-oss-process=style/test_watermark" } } 

    打开图片地址看看:

    生成测试图片

    速度很快,图片很漂亮,只是中间带水印,充值后成为付费用户,再生成的图片水印就自动取掉了。

    后端集成

    这里参考快海报官方给的最佳实践的逻辑参考图:

    集成逻辑

    所以后端只需要做一件事,就是提供一个 API 给客户端用,这个 API 被调用的时候去请求快海报的服务器,再把结果返回给小程序就好了。

    第 1 条附言    2020-10-20 15:03:23 +08:00
    价格下调为原始价格 1/3,最低均价 0.01 元 /张。
    33 条回复    2019-12-03 14:08:52 +08:00
    o00o
        1
    o00o  
       2019-10-25 13:50:26 +08:00 via Android
    建议水印换个地方,这样免费用的也可以帮你传播。现在的位置基本上不会有免费调用的吧
    paicha
        2
    paicha  
    PRO
       2019-10-25 15:29:22 +08:00
    支持一个
    Wichna
        3
    Wichna  
       2019-10-25 18:50:22 +08:00
    idea 不错,最好能够支持自定义模板。另外请求缓存的海报应该不计算费用吧?
    Croath
        4
    Croath  
    OP
       2019-10-25 19:29:44 +08:00
    @Wichna 可以传 url 或者直接传 html 进行渲染,参考文档: https://kuaihaibao.com/doc/docs/html.html
    Croath
        5
    Croath  
    OP
       2019-10-25 19:30:10 +08:00
    @o00o 感谢建议,在考虑如何让水印更美观一些
    Croath
        6
    Croath  
    OP
       2019-10-25 19:30:19 +08:00
    @paicha 谢谢
    paicha
        7
    paicha  
    PRO
       2019-10-25 19:35:21 +08:00
    建议可以去小程序开放社区推广一下
    Croath
        8
    Croath  
    OP
       2019-10-25 19:46:15 +08:00
    @paicha 好主意,我去发一下
    Croath
        9
    Croath  
    OP
       2019-10-25 19:53:08 +08:00
    @Wichna 忘掉一个问题了。

    缓存其实是说开发者应该自己判断是否要做缓存:

    - 如果每个用户分享的图片都一样,那么应该做一个全局缓存
    - 如果用户分享同一篇文章(商品)的图片都一样,应该针对商品(文章做缓存)
    - 如果一个用户可能多次分享同一张图片(比如自己的邀请图),那么应该针对用户做缓存
    - 如果每个用户每次生成的图都有差别(比方说用户头像的差别或二维码的差别),那么不应该做缓存,每次都应该重新生成
    natforum
        10
    natforum  
       2019-10-25 20:57:45 +08:00
    我看错了,我以为这个是提取微信朋友圈图片的
    musi
        11
    musi  
       2019-10-25 22:09:30 +08:00
    我之前做了一个用的是第二种方案,对于特定的海报来说可能就是用户的信息不一样,直接基于设计师给的底图再用程序直接绘制就好了,所以大部分工作还是设计师做的,后端只需要调整一下字体和位置就行了。写好程序后直接扔到阿里云的函数计算上,调用次数前多少次还免费来着。生成的海报直接上传到 oss 里,用户再次生成的时候直接从 oss 里取就好了。
    Croath
        12
    Croath  
    OP
       2019-10-25 23:43:57 +08:00 via iPhone
    @musi 嗯你这个开发流程也不短…做这个服务还是主要服务新手和小团队吧
    Blacate
        13
    Blacate  
       2019-10-26 00:22:46 +08:00 via iPhone
    我们现在就是用方案 3 自己开发了一个
    Croath
        14
    Croath  
    OP
       2019-10-26 01:12:16 +08:00
    @Blacate 成本怎么样
    dqsife
        15
    dqsife  
       2019-10-26 14:04:55 +08:00
    注册需要邀请码?
    Croath
        16
    Croath  
    OP
       2019-10-26 15:43:38 +08:00
    @dqsife 不填也可以呀。
    Blacate
        17
    Blacate  
       2019-10-27 14:00:12 +08:00
    @Croath 额 使用频率不高 所以就随便用一台服务器跑着
    quietjosen
        18
    quietjosen  
       2019-10-27 17:17:40 +08:00
    当初用了方案 1,痛苦…这个对个人开发者和小团队,是很好的东西。
    gaowhen
        19
    gaowhen  
       2019-10-30 15:34:12 +08:00
    https://developers.weixin.qq.com/community/develop/article/doc/00008c6f3f83888b176946d3d51413

    试了一下,接入很方便。这件事情吧,我觉得重点不是实现成本,而是性能一般的服务器根本抗不住多少请求,性能好的服务器,如果到不了一定请求量,绝大部分资源都被浪费了,根本就是得不偿失。一年 1000+ 的服务器费用,能买 20000+ 次调用,对个人开发者或者小团队来说,足够用很久了。
    Croath
        20
    Croath  
    OP
       2019-10-30 15:51:29 +08:00
    @quietjosen 如果有新项目想迁移过来,我可以协助解决
    Croath
        21
    Croath  
    OP
       2019-10-30 15:52:42 +08:00
    @gaowhen 小团队和独立开发者来说,综合成本降低 2/3 以上应该问题不大。
    Rwing
        22
    Rwing  
       2019-11-04 14:45:13 +08:00
    不错,挺好的
    Croath
        23
    Croath  
    OP
       2019-11-04 14:55:20 +08:00
    @Rwing 谢谢
    marvinemao
        24
    marvinemao  
       2019-11-04 15:53:48 +08:00
    不错,赞
    littleb
        25
    littleb  
       2019-11-07 17:38:45 +08:00
    用过一个类似的,叫创客贴
    Croath
        26
    Croath  
    OP
       2019-11-08 11:41:05 +08:00
    @littleb 嗯嗯见过,类似的产品有不少,但是这些主要是 C 端客户用的,自己拼一个单一成果。

    我们的服务是给 B 端客户用的,动态去为每一位 C 端客户实时生成不同的海报图。
    Dowding
        27
    Dowding  
       2019-11-26 10:53:04 +08:00
    我也选了方案一,确实比较麻烦,但是用服务的话就会对可靠性和是否长期维护有顾虑。
    Croath
        28
    Croath  
    OP
       2019-12-03 13:04:15 +08:00
    @takashiki 我们自己有几个小程序已经全部依赖这套服务了,长期服务没有问题,越多人使用共享均摊成本越低,目前客户规模已经能 cover 成本所以不存在因为亏损关闭服务的情况。

    后续我考虑将核心模块开源出来供大家使用,但是如果小团队搭建这套服务的话,成本就高了很多了。
    Croath
        29
    Croath  
    OP
       2019-12-03 13:04:39 +08:00
    @takashiki canvas 有个额外的问题我最近也没有找到特别好的处理方案,就是 emoji 绘制。
    ming
        30
    ming  
       2019-12-03 13:15:47 +08:00
    我们也做了一个内部服务,同时支持方案 1 和方案 2,但是方案三我们自己测试的时候发现首次渲染太慢了,你们做出来首次渲染需要多久啊?
    Croath
        31
    Croath  
    OP
       2019-12-03 13:18:39 +08:00
    @ming 我们不存在首次渲染和后续渲染的时间差异。200ms~500ms 不等,图片等资源如果都准备好了 200ms 就没问题。
    mzlzero
        32
    mzlzero  
       2019-12-03 13:42:15 +08:00
    好东西,帮转
    huhking
        33
    huhking  
       2019-12-03 14:08:52 +08:00 via iPhone
    支持,可以试试
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2775 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 12:41 PVG 20:41 LAX 04:41 JFK 07:41
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86