解决 uni-app 使用 Painter 生成商品海报真机模糊问题

每写一篇文章都需要前言进行背景的阐述,方便自己和其他遇到同样问题的朋友快速定位是否为同一类问题。

在开发 uni-app 的过程中分享商品时需要生成对应的商品海报图,个人也试了几款社区提供的插件,坑也是不少。但是仍然满足不了复杂的定制场景。

好在社区的大佬多,找到一块个人认为非常好,坑相对较少的插件。

Painter

地址已经贴上,需要的老铁可以去 Github下载。

下面说一下遇到的坑。

首先我们需要把 Painter 微信小程序插件下载下来,放到项目对应目录下,我这里是放在了 wxcomponents/painter 目录下。

你需要在哪个页面中使用这个插件,在 page.json 中将其加载进来。
解决 uni-app 使用 Painter 生成商品海报真机模糊问题

然后我们就可以在组件中使用。

解决 uni-app 使用 Painter 生成商品海报真机模糊问题
可能有朋友会问,palette 是什么作用。当然,它们官方文档也写的明明白白的,palette 字段作为画图数据的数据源,图案数据以 json 形式存在。说白一点就是,你生成的这个海报长什么样子,是需要你用 json 来描述。比如:

解决 uni-app 使用 Painter 生成商品海报真机模糊问题
我们需要将这些 json 数据传递给 painter 组件,它通过 canvans 进行画图。内部画完之后,会生成一个图片地址通过 @imgOk 自定义事件通知你接受。然后我们只需要把这个图片展示出来,如果需要用户保存这个图片海报,我们可以在图片下面提供几个按钮,让用户点击下载。

那么问题是这么多 json 数据,我要特么一行一行写和调试吗?

当然不是,Painter 官方给你提供了在线海报生成工具。超级好使

在线地址为 https://lingxiaoyi.github.io/painter-custom-poster/

你自己画完之后,将代码复制一份。

所以 palette 属性就是用于接收这些 json 数据。

还有一点需要提一下,我们需要将 painter 组件渲染出的元素移出屏幕之外,我们只需要它给我们返回的图片路径,然后我们自己渲染这个图片。

开始运行,成功生成了!

但是发现一个问题,这个海报生成的在真机上预览很模糊,模糊的你都不肯接受,这究竟是什么原因呢。

Painter 内部生成图片时,调用的是微信的 canvasToTempFilePath API。很大关系是和这个有关系,也就是和我们在组件上使用的 widthPixels 属性有关。

widthPixels 这个属性究竟是干嘛的? 起到了什么作用呢?

下面是 Painter 内部通过调用 wx.canvasToTempFilePath 生成图片的代码,发现内部用到了 destWidth 属性,也就是我们组件上使用的 widthPixels,目前我们使用的值是 375
解决 uni-app 使用 Painter 生成商品海报真机模糊问题

微信文档关于 canvasToTempFilePath 属性描述
解决 uni-app 使用 Painter 生成商品海报真机模糊问题

微信官方文档属性说明,表示输出的图片宽度。What?

难道如果将 widthPixels 指定为0,图片的宽度就是 0 了吗?
当然不是:

官方解释为: 存储图片的时候是按物理像素存的,canvas 用的是逻辑像素,所以要做一下转换

如果导出的图片是按照原始尺寸的话,就会出现很模糊的现象,因为屏幕密度的问题。所以需要将图片的宽度在 canvans 生成图片下进行 2 - 3 倍的放大。

然后生成的图片在手机上就会显真,不会出现模糊现象。

所以将 widthPixels="2080" 设置成了我画布的好几倍,然后生成的图片渲染出来在真机上调试不会出现模糊问题。

此篇文章会一直更新,如果还遇到相关的坑,会继续在这篇文档内总结。