图片处理(海报生成 and 二维码生成),由前端处理还是后端处理好? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
AquanllR
V2EX    程序员

图片处理(海报生成 and 二维码生成),由前端处理还是后端处理好?

  •  1
     
  •   AquanllR 2021-02-08 10:18:55 +08:00 6409 次点击
    这是一个创建于 1713 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前端生成慢,后端生成样式难把控。 想看看大佬们的看法和建议

    56 条回复    2024-07-25 12:31:47 +08:00
    guoziq09
        1
    guoziq09  
       2021-02-08 10:26:44 +08:00
    我个人认为是前端,前端 1v1,后端 1vN 。
    bugmakerxs
        2
    bugmakerxs  
       2021-02-08 10:27:34 +08:00
    前端,后端生成过,日常低效接口 top10
    Symo
        3
    Symo  
       2021-02-08 10:28:00 +08:00   1
    反了吧, 前端生成样式才是比较难把控的. 用 html2canvas 转图片可能会遇到手机兼容性不好导致偏移的情况. 而且基本上没有办法发现.
    Orenoid
        4
    Orenoid  
       2021-02-08 10:30:24 +08:00
    前端生成可以把计算的压力分散到各个用户的设备上,但是少部分设备可能有兼容性问题,导致生成的图片样式不完全统一
    shyling
        5
    shyling  
       2021-02-08 10:31:15 +08:00
    对海报没啥概念,二维码应该是前端做更好点
    leeguo
        6
    leeguo  
       2021-02-08 10:31:59 +08:00
    才做过, 前端 有封装好的, 大小可调, 很方便
    Orenoid
        7
    Orenoid  
       2021-02-08 10:33:12 +08:00
    @Orenoid #4 除了生成图片的计算负载,后端生成可能还要上传 /下载图片,相对来讲也更费时间,个人倾向于前端生成。
    AquanllR
        8
    AquanllR  
    OP
       2021-02-08 10:35:54 +08:00
    @guoziq09 有道理,服务器生成得 1 对 N,不过后端可以做缓存处理
    AquanllR
        9
    AquanllR  
    OP
       2021-02-08 10:36:06 +08:00
    @bugmakerxs 建议前端吗?
    AquanllR
        10
    AquanllR  
    OP
       2021-02-08 10:37:20 +08:00
    @Orenoid 嗯,现在 2 个方案实现了,后端是要上传 oss,前端展示
    imgbed
        11
    imgbed  
       2021-02-08 10:44:09 +08:00 via Android
    前端的 canvas 已经很强大了,很多网页游戏都做得来,何况静态海报。写个专门的 js 作为海报生成专用吧
    bugmakerxs
        12
    bugmakerxs  
       2021-02-08 10:46:44 +08:00
    @AquanllR 是的
    sarices
        13
    sarices  
       2021-02-08 10:48:50 +08:00
    后端调用 Puppeteer 生成海报,缓存到 cdn
    maplerecall
        14
    maplerecall  
       2021-02-08 11:02:24 +08:00 via Android
    涉及文本的走后端,前端没法统一字体,除非对文字样式和排版要求不高。只是图片加二维码就走纯前端,图片不太多的情况下即使手机处理也非常快了。
    vevlins
        15
    vevlins  
       2021-02-08 11:04:15 +08:00
    前端,省省流量和内存吧,都是钱呀
    preach
        16
    preach  
       2021-02-08 11:05:08 +08:00
    看业务的量,过 10 万 uv 走前端
    kisshere
        17
    kisshere  
       2021-02-08 11:24:47 +08:00   1
    if($is_generated_poster_dynamically)
    {
    后端走起();
    }elseif($daily_pv>100000)
    {
    前端走起();
    }
    kisshere
        18
    kisshere  
       2021-02-08 11:26:30 +08:00
    @kisshere #17 第一个打错了,是前端走起
    TimPeake
        19
    TimPeake  
       2021-02-08 11:30:41 +08:00   1
    二维码可以前端弄,但是海报真的不好搞。有人说 canvas 已经很强大了 是,没错 ,但是相应的工具包 html2canvas bug 很多,唯一能用的也只有这个吧。
    weixiangzhe
        20
    weixiangzhe  
       2021-02-08 11:49:59 +08:00 via Android
    前端处理就好啦,全部 canvas 渲染
    throns
        21
    throns  
       2021-02-08 12:03:35 +08:00 via iPhone
    @TimPeake 做过类似的,html2canvas 问题挺多的,img 标签有问题,字体也有问题。最后还是通过调用 Puppeteer 来截图的,对了,还需要在服务器上安装字体,挺麻烦的,不过后面弄成 docker 镜像,部署还算方便
    AquanllR
        22
    AquanllR  
    OP
       2021-02-08 12:03:47 +08:00
    走的是阿里的 oss,估计后面会烧钱
    AquanllR
        23
    AquanllR  
    OP
       2021-02-08 12:04:26 +08:00
    @kisshere 是都走前端吗?
    wingoo
        24
    wingoo  
       2021-02-08 13:04:41 +08:00
    ali 的 oss 可以添加水印, 可以用这个功能生成海报
    killergun
        25
    killergun  
       2021-02-08 13:16:37 +08:00
    后端说前端好,前端说后端好
    markgor
        26
    markgor  
       2021-02-08 13:24:48 +08:00   4
    PC 端,html2canvas 浏览器不同内核版本 /html2canvas 不同版本都能蹦出一堆 BUG 。
    手机端,简单的 canvas 生成完成,但是不同品牌不同平台的小程序不一样的体验。

    最终:后端生成

    后来还涉及到原海报某些附带二维码,某些没有附带二维码,附带二维码的执行替换,没有附带二维码的对原图拉高插入二维码到底部....

    还好当初选择后端生成。

    当初想法和 1L 如出一辙。1V1 和 1VN 的区别,而且还省下带宽。可惜浏览器的差异化实在太恐怖了....现在后端生成性能其实还好吧,毕竟不需要每秒生成几十张,实际情况生成的并发量并不会太高,而且后端生成做做文件名缓存,防止重复生成即可了。
    markgor
        27
    markgor  
       2021-02-08 13:37:45 +08:00
    应该这样说吧,取决场景和业务;

    小程序前端,canvas 一直有问题,加载字体绘画更加别想了。
    H5 前端:canvas 支持不一,出来效果往往事与愿违。
    但是如果单纯图片缩放叠加拉伸----那样前端没多大问题,偶尔走走样总会有的。
    后台表单类的,导出 PDF/JPG 等,通过 canvas 的话 CSS 部分属性不支持,table 边框支持不完善....建议后端
    复杂多平台等业务下:建议后端生成。
    AquanllR
        28
    AquanllR  
    OP
       2021-02-08 13:42:19 +08:00
    @markgor Get!
    AquanllR
        29
    AquanllR  
    OP
       2021-02-08 13:43:44 +08:00
    前端小程序有一个开源库 https://github.com/Kujiale-Mobile/Painter 其实复杂的也可以操作
    markgor
        30
    markgor  
       2021-02-08 13:54:20 +08:00
    @AquanllR 我之前是用 uniapp 多端开发的,直接在插件市场找过 2 个,最终测试都不符合需求。
    你可以试试看使用开源库那里的,如果能符合你需求那就直接前端生成。
    markgor
        31
    markgor  
       2021-02-08 14:01:34 +08:00
    @AquanllR 哈哈哈,刚去 Painter 那看了,你进去 issues 那看看。然后幻想一下,每当出现(微信 CANVAS 渲染 BUG 或插件 BUG ),客户小姐姐一直 @你的场景。如果是微信 canvas 问题,你能做的只有等微信修复,还要弄一堆复现代码给微信。可是你能等业务不能等,小姐姐天天 @你,你能干的只有要么干掉小姐姐,要么干掉 canvas,要么被老板干掉
    u6pM63mMZ34z32cE
        32
    u6pM63mMZ34z32cE  
       2021-02-08 14:08:01 +08:00
    这得看谁的老大级别大, 像这种前后端都能做的需求, 一般都是级别小的人做
    AquanllR
        33
    AquanllR  
    OP
       2021-02-08 15:18:19 +08:00
    @markgor 这样考虑的话,可控性的话,还是后端好。
    Exia
        34
    Exia  
       2021-02-08 17:05:40 +08:00
    做过,都是前端生成的,不知道这海报有多复杂,可以看前端是否能搞定。
    stevenkang
        35
    stevenkang  
       2021-02-08 17:36:05 +08:00
    我在想,这图片后端处理的话,是消耗 GPU 资源吧?然而大多数后端服务器 GPU 都很弱。所以到底是前端生成慢,还是后端生成慢呢?
    freakJacker
        36
    freakJacker  
       2021-02-08 20:42:51 +08:00
    前端没办法统一,除非都是图片拼接。
    后端烧性能。
    这东西也不难,一般能前端做就前端做了
    DiamondYuan
        37
    DiamondYuan  
       2021-02-08 20:53:08 +08:00
    serverless 生成
    max1024
        38
    max1024  
       2021-02-08 21:01:35 +08:00
    前端生成不难吧。
    zqjnew
        39
    zqjnew  
       2021-02-08 21:19:06 +08:00 via Android
    二维码可以固定,然后跳的链接做动态代理,
    海报可以混合模式,即服务端做大块,前端做小块或整合
    OHyn
        40
    OHyn  
       2021-02-08 21:30:36 +08:00
    能接受效果不统一的,前端能做。
    Lemeng
        41
    Lemeng  
       2021-02-08 22:12:34 +08:00
    前端
    foxcell
        42
    foxcell  
       2021-02-09 08:18:43 +08:00
    前端
    没有必要的计算量还是扔给用户端分担
    markgor
        43
    markgor  
       2021-02-09 12:22:56 +08:00
    @AquanllR 后端结果统一且稳定,而且生成海报这个业务并发量也不大...
    @Exia 前端其实不可控因素太多,特别是多端环境下的开发...哪怕只是 H5,不同内核呈现出的效果都有一定差异。
    @stevenkang 想多了,后端处理基本都是跑 CPU 资源,占用的大户是 CPU>带宽>内存。

    其实结合上面所有的观点,都是建议 前端生成,理由是节省资源和带宽。

    这点我同意,但我也给我之前项目经验给你参考:

    业务 1:生成业务员名片,格式固定,获取头像、姓名、部门、二维码,复制到模板对应位置即可。
    方案:PC 前端生成名片
    坑:浏览器分辨率,浏览器缩放,屏幕大小(有些用 PC,有些用手机)
    处理结果:被人 @了 2 周,终于稳定了;其中缩放功能导致的异常没法解决,只能建议他们别缩放。

    业务 2:客户手机端产品海报生成,产品图为主图,背景为产品图+300 像素,左边放产品名称和推荐人头像姓名,又边放产品链接二维码;
    方案 1:前端生成
    坑:产品名称过长,昵称含有特殊字符的,直接 GG 了,多端( h5,微信小程序,抖音小程序)展示的效果不一致,其中印象最深的是微信小程序 IPHONE7 机型,完全走样。基本功能上线后天天被人 @ 。

    方案 2:后端生成
    坑:由于后续海报图增加了价格显示,但是产品价格会改变,当初做缓存的时候没考虑到这个因素,导致某天突然被 @说海报的价格不一致......。
    处理结果:把用户昵称 + 产品 ID + 产品价格 做个 MD5,请求是判断是否存在,存在就直接返回,不存在就走生成逻辑。
    ---至今稳定,也没出现 CPU 毛刺之类,后续还加入了 QRCODE 查找替换的功能....
    后来也有过小坑,带宽偶尔出现毛刺,查监控找不到规律。
    某来突然发现是用户下载海报时候导致的。因为部分图片大小逼近 4~5MB 。(产品主图有做 CDN 缓存,但是生成的海报没做缓存)
    解决方法:用户->CDN->COS->源;



    结合上面自身案例,结论:
    后端生成
    优点:稳定,生成结果统一、后期海报需求变复杂的情况下也能支撑。
    缺点是:
    1 、原图过大的话海报会影响带宽----通过 CDN 解决
    2 、防止 CPU 瞬间飙升---通过判断文件是否已经生成(缓存),要求再高的话可以单独一个服务出来。


    前端生成
    优点:节省计算资源、带宽;
    缺点:不同终端不同内核结果不一,无法支撑复杂业务;



    BTW:
    如果你把标题改为 “后端处理海报 AND 二维码 的能力 和前端处理的能力对比”,估计你会得到不一样的结果。
    zuiye111
        44
    zuiye111  
       2021-02-09 15:21:16 +08:00   1
    正好最近在做一个海报中心项目,当时做方案时也是在考虑前端生成还是后端生成,所以这个问题我也回答下
    我们的产品形态是小程序
    1 、前端生成
    优点:对后台友好,由于我们项目后台都是 C++,要找一个画图的库还是比较麻烦,前端合成可以降低后端开发压力,其次可以充分利用客户端计算性能,灵活
    缺点:就像上面说的,需要考虑不同机型适配,字体问题,其次,要考虑前端生成的海报如何传给后台?传二进制流?还是合成后上传 CDN 再给后台?再者,由于我们还支持用户上传图片,小程序里可能支持性不够好
    2 、后台合成
    优点:可控性,可靠性,统一性更好
    缺点:开发成本较高
    最终和前端同事讨论比较,还是选择后台单独写个合成图片的服务,前端使用 svg 渲染海报模板,用户编辑后,再把 svg 转 json 传给后台,后台合成图片并上传 cdn,返回给前端 cdn 地址,最终,经过优化,合成的速度基本控制在 1~2s 。
    目前我们海报中心小程序已经在灰度中,支持特殊字体,好友码,上传图片等功能,如下图
    https://wx.gtimg.com/resource/feuploader/202102/b540d53198dd75d1b2c2d9cad6453014_1080x2337.jpg
    sujin190
        45
    sujin190  
       2021-02-09 18:18:49 +08:00 via Android
    @stevenkang 后端 2d 绘图,cpu 绘制的吧,而且现在用的比较多的云主机似乎没有 gpu 的吧
    AquanllR
        46
    AquanllR  
    OP
       2021-02-20 12:00:16 +08:00
    @markgor 感谢耐心的解答
    AquanllR
        47
    AquanllR  
    OP
       2021-02-20 12:00:45 +08:00
    @DiamondYuan 是个不错的方案,纳入考虑范围
    AquanllR
        48
    AquanllR  
    OP
       2021-02-20 13:43:59 +08:00
    @markgor 有一个疑问就是业务 2 的方案 2,会出现一种场景就是,产品名称参数修改了,海报上面的标题因为已经存在了,不会重新生成,而导致海报上的数据是旧的问题。
    感觉得商品编辑修改的时候同步去修改
    markgor
        49
    markgor  
       2021-02-20 14:28:39 +08:00
    @AquanllR
    >产品名称参数修改了,海报上面的标题因为已经存在了,不会重新生成,而导致海报上的数据是旧的问题。
    前端传:价格-产品标题-产品图片 url-openID(userID)-用户名称
    后端:根据上面的信息,组合字符串,在走个 MD5,出来的结果就能保证一致了。

    >感觉得商品编辑修改的时候同步去修改
    应该不可以吧,看你业务海报图是否需要用户信息。
    如果不需要用户信息可以。
    如果需要用户信息那你触发的地方只有用户点击生成后吧?
    markgor
        50
    markgor  
       2021-02-20 14:34:47 +08:00
    @AquanllR
    前端:POST->price 、title 、posterUrl 、openID 、nickName
    后端:
    //简单:
    $FILENAME = MD5($title . $posterUrl . $price . $openID . $nickName);
    //复杂:(感觉没必要)
    $FILENAME = MD5(md5($title) . md5($posterUrl) . md5($price) . md5($openID) . MD5($nickName));

    //判断海报是否已经生成:
    $FILENAME .= '.jpg';

    if(is_file($_PATH_TO_DIR . $FILENAME)){
    //存在:输出
    }

    //不存在:进入生成流程





    --------------
    不知道怎么表达,文字功底薄弱,
    中心思想就是把影响生成的条件(变量)并在一起,生成个 MD5,然后判断文件是否已经生成。
    AquanllR
        51
    AquanllR  
    OP
       2021-02-20 16:05:26 +08:00
    @markgor 十分感谢!现在问题已经很明朗了~再次感谢
    AquanllR
        52
    AquanllR  
    OP
       2021-02-20 16:05:45 +08:00
    感谢大家的热情讨论!
    xmsz
        53
    xmsz  
       2023-02-09 12:08:12 +08:00
    综合 我认为应该是后端...

    如果直说浪费后端资源 /客户端 1v1 的,那应该没做过,或者天真一点的,或者海报就很简单,或者是完全不追求生成效果,或者完全不管用户反馈的场景...


    前端生成的问题就是
    1. 复杂海报每次生成需要时间,是每次,用户用一次生成一次。体验并不好,除非你生成后再放到 CDN 上(那还不如...)。我们之前开发的头像小程序就是,蛮尴尬的...
    2. 遇到字体文件,吐血... 你总不能给客户端下载个 10m 的字体?
    3. 最恶心的来了,你这个服务只能兼容 90%左右的情况,而剩下 10%会搞死你
    ...

    特别是最后一点,就算你兼容的是 99%,那 1%还是会搞死你。
    一般的人根本不懂兼容,他只觉得没能兼容 100%就是你的问题,你直接气疯...
    而且我们公司有个后端程序员居然也怎么想... 真的尴尬


    对于后端来说,只需要考虑『资源』问题
    对于产品、设计、前端来说,要考虑的不仅仅是『资源』,还要『兼容』、『效果』、『体验』....

    所以综合起来肯定是后端生成


    当然,如果其他前端好的方案也可以讨论
    我们 web 端和小程序,基本已经穷尽了,当然自己也用 canvas 写了,但效果真的...
    AquanllR
        54
    AquanllR  
    OP
       2023-02-09 14:58:36 +08:00
    我们开始是先使用了前端生成的,最后最终方案走的是后端生成方案进行了
    @xmsz
    lizy0329
        55
    lizy0329  
       2024-07-25 12:24:25 +08:00
    1 Dom -> image ( IOS 兼容性很差)
    2 Dom -> base64 ( html2canvas 有很多 BUG )
    3 Dom -> svg -> base64 -> 七牛返回 png 等 image

    3 这样可行?
    lizy0329
        56
    lizy0329  
       2024-07-25 12:31:47 +08:00
    @zuiye111 yes
    SVG to Image 在后端进行,可用性是最棒的
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2555 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 02:13 PVG 10:13 LAX 19:13 JFK 22:13
    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