[已解决]后段在图片上加用户基础信息,方案讨论
发布于 6 年前 作者 chenzeZzz 4108 次浏览 来自 问答

后段在海报上添加当前用户的头像, 邀请码,战绩,生成一张新的图片,传到服务器,返回给客户端一个url,客户端分享到微信。 之前的做法是用images库拼接,并且可以预处理,但是新的需求是,需要等客户端返回一个战绩我才能生成, 并且,我需要批量操作,image这个库生成一张图片有时需要2000+ms, 老板们有什么好的建议吗,客户端说了,他做不了

24 回复

我觉得这东西应该由客户端完成吧,你只用生成一个邀请码给客户端就行了

@im-here 客户端说做不了,之前需求紧的,我后段这边已经实现了,但是这次的需求加了战绩的信息,我无法预处理

@chenzeZzz 这个前端可以开了

@chenzeZzz 和客户端沟通下吧,不管是从性能和效率上都应该客户端来做这事,当然如果客户端实在太忙,要你服务端来做的话,你把利弊给他以及你的领导讲清楚。

这个前端为什么做不了,图片传输也是需要网络资源的好伐? 碰巧今天看到个好东西,图片合成:https://github.com/lukechilds/merge-images 你是用的这个吗?

@im-here @wangchaoduo @2linziyi2 感谢各位的意见,最后的方案是,客户端增加一个战绩海报按钮,点击按钮的时候,后段开始针对性的生成图片,可以稍微减缓一点压力,不过用户量上去了,还是需要换方案的。

svg格式

来自酷炫的 CNodeMD

@zswnew 我text-to-svg转了5个数字,需要500+ms,有更好的库吗 From Noder

文字转svg -> svg转png -> 合并图片 可以参考一下别人的 https://cnodejs.org/topic/583c5d9fba57ffba06c24a89

@xiaoxi
一开始我看下面有 i5ting 的评论,评论大多都是666,我想这个方案大概没问题的了,就直接在项目里用了, 关于这个帖子上的test,结果有两个注意点: 1,text-to-svg 这个库转5个数字成png 单次 需要 500 ms 左右, for循环100次 需要 7000+ms。

  1. 我的背景图片100k ,机子是mbp, 整个流程跑下来,需要的时间如下, ✗ node test.js --> xixi: 6613.657ms

和这个作者的500ms 相差甚远。 有点怀疑node是不是不太适合处理图片

你可以试一下child_process.exec去调用GraphicsMagick(可以开多线程来生成)或者ImageMagick的命令去生成图片试试,应该是能快些。 还有生成图片最好单独放一台机器,这样应该能稍微减免一点对其它服务的影响。 其实就算是C生成图片单线程合成一张也不会太快。 还有你上面的测试相当于排队生成了吧,你改为调用http服务,因为http服务每一个请求都可以作为一个异步方法,这样应该会快些 还有可以考虑图片的复用,比如生成图像有两步,先加头像,后加战绩,把先加头像的图片根据用户id缓存起来,等下次用的时候就不用加头像了,直接加战绩。

来自酷炫的 CNodeMD

@zy445566 用了一天的时间,参考了你的方案,在另一台机子上起了个服务专门搞图片操作,用http来调用,没有分布式的经验,没想到好的办法。 gm这个工具比text-png-svg 快的不是一点半点,但是比较坑的是,gm的依赖很多,安装繁琐。 另外想请教下,exec 去调gm, 我怕用户请求多了,我可能需要用队列,但是,如果这时候这个服务跪了,有什么好的解决办法

@chenzeZzz 专门搞台服务器做这个事情就是为了防止这个东西崩会影响其它服务,简单的做法就是自动重启服务就行。没有什么服务能保证不跪的。 分布式我建议你现阶段不要去想。就算用简单搭nginx搞lvs去分发只不过把负载压到了网卡上,到时候流量一上来网卡就扛不住了。真要搞,处理图片的集群和分发图片的集群都要分离,成本太高,有这成本你还不如直接用现有的云来处理,反倒便宜。 除非实在扛不住了,我觉得没必要加队列,不过这也算是一个简单的防崩的办法。 要是安装简单,依赖少,这个早就普及了。在没什么资源的情况下,处理图片服务到哪都是一个难题。

七牛有图片添加文字的api

@chenzeZzz 一定要做的话,后端也可以用 node-canvas来做,不只是文字,图片也可以画就是了,但是效率也不能算高而且特别吃资源 最好还是给前端数据让前端渲染,安卓的话,做个界面直接可以截出当前界面绘制的图,非常方便。h5就更简单了,自己写个canvas画上去,输出到img标签就完事了

@aojiaotage 我们的客户端是,u3d写的,u3d那说,只能截屏本地保存,然后把本地保存的图片发送到微信, 而h5 那边说, 可以画图片,但是生成的图片地址是base64,不能传给客户端,我没有研究u3d/h5该怎么实现, 也没必要讨论人的问题,现在的我后台这边解决的办法是 11 楼的方案。 关于 node-canvas 这个库, 依赖也很多,需要 pkg-config cairo, 我已经按照文档步骤装了,依然报错(Package ‘gobject-2.0’, required by ‘cairo’, not found) 在mac上装了半天没搞定。 最后请教个问题,我们客户端那边有的页面是直接掉 h5, 每次加载都会卡顿, 前段说需要拿资源,图片,样式 , js什么的,现在很多产品都嵌入h5,相比客户端直接提供页面,优点在哪

@yuedun 是的,刚看到,十分感谢🙏

回你16楼最后嵌入h5和客户端直接提供有点在哪,最主要一点就是h5这东西资源是放在服务端的,里面展示的内容可以随时改,而放在客户端的话要么热更要么重新提包

至于你前面说的每次加载都会卡顿应该不至于啊,你看王者荣耀里面的 社区 那个按钮 就是加载的web页面

@im-here 这是一个排行榜的页面,大致流程是,从客户端拿token, 发请求到服务器拿排行信息,最后生成页面显示。 server这边,我是在redis里取的,正常情况都不会卡的,另外 我看了那个h5页面的请求,有拿图片的操作,如果图片很大,可不可以把图片材料放在客户端包,h5直接拿本地的素材

屏幕快照 2018-05-11 下午6.34.27.png

@chenzeZzz 不是很懂客户端,但是据我所知的,图片放本地应该是不行的。 客户端加载你这个排行榜的页面就好比你用浏览器访问一样,不能加载本地资源的

其实我理解的你的排行页面显示的内容就是一个table对吧? 那zepto.js应该可以不用啊

arrow.png和rank_head.png这个两张图应该不大吧 21Rule.png是什么?排行规则说明么?

我的建议是能用文字展示的尽量不要用图片,能用css搞定的尽量不要用图片

你客户把你的这个url在Chrome里访问下,然后打开Network,勾选disable cache,多访问几次,看看加载完毕要多长时间,同时看看各个资源文件加载要多长时间

@chenzeZzz cario 的安装的确是比较麻烦,各个平台都是不一样的 官网

我还没有做过这个生成图片的。但是有一个想法,谷歌的puppeteer是无头浏览器,如果能写一个网页模板,渲染之后,用puppeteer来截图,这样生成图片应该可以。有考虑过吗?当然性能我不清楚。不过我做爬虫的时候,用puppeteer截图,速度还是可以的。

@ilaipi 看下了这个工具,类似于我在16楼说的,客户端那边截屏然后保存图片之后发送,puppeteer 是把截屏的操作移到了后段; 把分享的图片用h5写,然后puppeteer去截h5的图片。 这个工具很强,也符合我目前的这个需求,但是我的这个需求是病态的,是不得已而为之,暂时没想到 puppeteer 能落地的合适的的客户需求。 关于性能, node-modules 有 170+m, 截百度的页面,fullpage 全屏截取和部分截屏(按照5寸屏幕的尺寸)大概都在 1800-2200ms, 但是截我们服务器的排行榜图片,或者其他dom结构复杂一些的页面,普遍需要3000+ms

@im-here 你的建议很细,关于排行榜页面这边,除了你上面的几点,因为我这边需要传用户头像的地址给他,他还要拿用户的头像,目前优化的点是下拉预加载。

回到顶部