V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
AquanllR
V2EX  ›  程序员

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

  •  
  •   AquanllR ·
    aquanlerou · 87 天前 · 2908 次点击
    这是一个创建于 87 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

    最终:后端生成

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

    还好当初选择后端生成。

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

    小程序前端,canvas 一直有问题,加载字体绘画更加别想了。
    H5 前端:canvas 支持不一,出来效果往往事与愿违。
    但是如果单纯图片缩放叠加拉伸----那样前端没多大问题,偶尔走走样总会有的。
    后台表单类的,导出 PDF/JPG 等,通过 canvas 的话 CSS 部分属性不支持,table 边框支持不完善....建议后端
    复杂多平台等业务下:建议后端生成。
    AquanllR
        28
    AquanllR   86 天前
    @markgor Get!
    AquanllR
        29
    AquanllR   86 天前
    前端小程序有一个开源库 https://github.com/Kujiale-Mobile/Painter 其实复杂的也可以操作
    markgor
        30
    markgor   86 天前
    @AquanllR 我之前是用 uniapp 多端开发的,直接在插件市场找过 2 个,最终测试都不符合需求。
    你可以试试看使用开源库那里的,如果能符合你需求那就直接前端生成。
    markgor
        31
    markgor   86 天前
    @AquanllR 哈哈哈,刚去 Painter 那看了,你进去 issues 那看看。然后幻想一下,每当出现(微信 CANVAS 渲染 BUG 或插件 BUG ),客户小姐姐一直 @你的场景。如果是微信 canvas 问题,你能做的只有等微信修复,还要弄一堆复现代码给微信。可是你能等业务不能等,小姐姐天天 @你,你能干的只有要么干掉小姐姐,要么干掉 canvas,要么被老板干掉
    mebtte
        32
    mebtte   86 天前
    这得看谁的老大级别大, 像这种前后端都能做的需求, 一般都是级别小的人做
    AquanllR
        33
    AquanllR   86 天前
    @markgor 这样考虑的话,可控性的话,还是后端好。
    Exia
        34
    Exia   86 天前
    做过,都是前端生成的,不知道这海报有多复杂,可以看前端是否能搞定。
    stevenkang
        35
    stevenkang   86 天前
    我在想,这图片后端处理的话,是消耗 GPU 资源吧?然而大多数后端服务器 GPU 都很弱。所以到底是前端生成慢,还是后端生成慢呢?
    freakJacker
        36
    freakJacker   86 天前
    前端没办法统一,除非都是图片拼接。
    后端烧性能。
    这东西也不难,一般能前端做就前端做了
    DiamondYuan
        37
    DiamondYuan   86 天前
    serverless 生成
    max1024
        38
    max1024   86 天前
    前端生成不难吧。
    zqjnew
        39
    zqjnew   86 天前 via Android
    二维码可以固定,然后跳的链接做动态代理,
    海报可以混合模式,即服务端做大块,前端做小块或整合
    OHyn
        40
    OHyn   86 天前
    能接受效果不统一的,前端能做。
    Lemeng
        41
    Lemeng   86 天前
    前端
    foxcell
        42
    foxcell   86 天前
    前端
    没有必要的计算量还是扔给用户端分担
    markgor
        43
    markgor   86 天前
    @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   85 天前
    正好最近在做一个海报中心项目,当时做方案时也是在考虑前端生成还是后端生成,所以这个问题我也回答下
    我们的产品形态是小程序
    1 、前端生成
    优点:对后台友好,由于我们项目后台都是 C++,要找一个画图的库还是比较麻烦,前端合成可以降低后端开发压力,其次可以充分利用客户端计算性能,灵活
    缺点:就像上面说的,需要考虑不同机型适配,字体问题,其次,要考虑前端生成的海报如何传给后台?传二进制流?还是合成后上传 CDN 再给后台?再者,由于我们还支持用户上传图片,小程序里可能支持性不够好
    2 、后台合成
    优点:可控性,可靠性,统一性更好
    缺点:开发成本较高
    最终和前端同事讨论比较,还是选择后台单独写个合成图片的服务,前端使用 svg 渲染海报模板,用户编辑后,再把 svg 转 json 传给后台,后台合成图片并上传 cdn,返回给前端 cdn 地址,最终,经过优化,合成的速度基本控制在 1~2s 。
    目前我们海报中心小程序已经在灰度中,支持特殊字体,好友码,上传图片等功能,如下图
    https://wx.gtimg.com/resource/feuploader/202102/b540d53198dd75d1b2c2d9cad6453014_1080x2337.jpg
    sujin190
        45
    sujin190   85 天前 via Android
    @stevenkang 后端 2d 绘图,cpu 绘制的吧,而且现在用的比较多的云主机似乎没有 gpu 的吧
    AquanllR
        46
    AquanllR   75 天前
    @markgor 感谢耐心的解答
    AquanllR
        47
    AquanllR   75 天前
    @DiamondYuan 是个不错的方案,纳入考虑范围
    AquanllR
        48
    AquanllR   74 天前
    @markgor 有一个疑问就是业务 2 的方案 2,会出现一种场景就是,产品名称参数修改了,海报上面的标题因为已经存在了,不会重新生成,而导致海报上的数据是旧的问题。
    感觉得商品编辑修改的时候同步去修改
    markgor
        49
    markgor   74 天前
    @AquanllR
    >产品名称参数修改了,海报上面的标题因为已经存在了,不会重新生成,而导致海报上的数据是旧的问题。
    前端传:价格-产品标题-产品图片 url-openID(userID)-用户名称
    后端:根据上面的信息,组合字符串,在走个 MD5,出来的结果就能保证一致了。

    >感觉得商品编辑修改的时候同步去修改
    应该不可以吧,看你业务海报图是否需要用户信息。
    如果不需要用户信息可以。
    如果需要用户信息那你触发的地方只有用户点击生成后吧?
    markgor
        50
    markgor   74 天前
    @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   74 天前
    @markgor 十分感谢!现在问题已经很明朗了~再次感谢
    AquanllR
        52
    AquanllR   74 天前
    感谢大家的热情讨论!
    关于   ·   帮助文档   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3225 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 05:40 · PVG 13:40 · LAX 22:40 · JFK 01:40
    ♥ Do have faith in what you're doing.