微信小程序上直接加载缩略图

Posted by 橙叶 on Sat, Sep 26, 2020

最近在做一个微信小程序,小程序首页是一个列出信息并附带图片的列表。 这种小图理所应当地应该使用缩略图,主要是为了节省流量。但是微信似乎并没有提供缩略图的功能,于是就只好加载全图。

后来就出了问题,起因是其中一个头像换了个体积很大的图片,但是还是在加载原图,结果导致整个页面卡顿异常,乃至出现黑块。这个问题本来也存在,就是在下拉加载的时候会出现撕裂,但没有这么严重。

一番分析之后认为是加载的图片过大导致的(怀疑微信小程序的性能,这才到哪儿就这样了),于是决定换成缩略图。

图片是存放在微信云服务的存储里面,微信小程序内部直接用的cloud://链接加载图片,也没有找到小程序对缩略图的支持方法。如此一来,似乎只有自己生成缩略图这一条路。

正好在编写后台时,用到了batchDownloadFile的接口,这个接口可以返回图片的外链,留意一下外链的格式:https://数字-云环境id-数字.tcb.qcloud.la/文件名的格式,如果在控制台将权限设置为所有人可读,就可以直接拼接出外链。

再看一下404的返回内容:

<Error>
<Code>NoSuchKey</Code>
<Message>The specified key does not exist.</Message>
<Resource>xxxx-xxxxx-xxxxx.cos.ap-shanghai.myqcloud.com/2133</Resource>
<RequestId>NWY0YzcwMWJfNTQyZjIyMDlfNmMxZl82OTAxNzM5</RequestId>
<TraceId>OGVmYzZ************kMTBiOWVmMDAxODc0OWRkZjk0ZDM1NmI1M2E2MTRlY2Mreg*****************************4Njk***************************c=</TraceId>
</Error>

微信云服务的存储功能不过是用的腾讯云的COS对象存储,对象存储一般是提供图像处理功能的,于是找到COS的文档中的图片处理部分 https://cloud.tencent.com/document/product/436/44880 。测试一下,可以使用。

https://xxxxxxxx.tcb.qcloud.la/example.jpg?imageMogr2/thumbnail/162x162"

在微信小程序里加一步将cloud://转换为外链的步骤就行了,这个可以使用wx.cloud.getTempFileURL(Cloud.getTempFileURL 文档),也可以如前文所述自己拼接出来(需要所有人可读)。

示例:

查询操作blabla.....
.then(({list})=>{
    return list.map((item)=>{
        /**
        * 因为之前直接加载完整图片,影响页面性能,浪费流量
        * cloud:// 格式的链接不能生成缩略图,将其转换成COS(腾讯的对象存储服务)的链接之后,
        * 加上参数得到缩略图
        */
        let filename = item.icon
        item.icon = 'https://数字-云环境id-数字.tcb.qcloud.la/' + filename + `?imageMogr2/thumbnail/125x125`
        return item
    })
})

关于数字-云环境id-数字,在微信开发者工具-云开发控制台-存储,随便找一个文件右键详情,在“下载地址”中就可以看到。

缩略图的大小如何选择呢?一般设个128x128这样差不多的数字就行了。最好的办法是根据不同屏幕进行适配。微信中常用的单位是rpx,图片的大小是px,需要先进行转换,可以用wx.getSystemInfowx.getSystemInfo 文档)来获得屏幕分辨率信息,然后根据信息进行转换:

rpx是将所有设备得宽度都视为750,用windowWidth除以750得到px,再乘以像素比,得到物理像素。


/**
 * 返回rpx和px的对应关系
 * 这里的px是设备物理像素
 */
function getRpx2px(){
  return new Promise((resolve, reject)=>{
    wx.getSystemInfo({
      success: (result) => {
      // 物理像素 = 窗口宽度/750 * 像素比
        resolve(result.windowWidth/750*result.pixelRatio)
      },
      fail: (msg)=>{
        reject(msg)
      }
    })
  })
}

这样我们就能得到rpx和物理像素的比例,将这个比例乘以小程序中图片的rpx尺寸,就可以得到物理尺寸

let rpx2px = await getRpx2px()
let px = Math.ceil(108 * rpx2px) // 图片设置为108rpx
// 拼接url
item.icon = 'https://xxxxxxx.tcb.qcloud.la/' + filename + `?imageMogr2/thumbnail/${px}x${px}`

如此,列表加载流畅。



comments powered by Disqus