# 如何处理用户上传的图片然后返回

# 目的

有很多情况下,我们需要对用户在客户端上传的文件进行相关处理,比如裁剪,压缩,加水印等等。

云托管对象存储并没有集成文件处理相关的扩展,如果我们想自己写一个服务来处理,具体的过程应该是什么样子的?

# 过程演化

由于cloud.callContainer的请求大小有限制,所以直接通过请求的方式传文件或图片信息给服务端是不现实的,所以我们可以用对象存储来做中转,具体的过程如下:

  1. 小程序中上传文件到对象存储,获取文件的fileid
  2. 小程序请求给处理文件服务,带入第1步的fileid
  3. 处理文件服务,通过 filid 读取对象存储中的文件,并进行处理,把处理后的文件上传到对象存储中,获取另一个fileid
  4. 服务中上传的 fileid 返回给小程序中,小程序根据 filid 下载文件,在前端展示

# 代码演示

我们写了一个服务演示了上述过程,使用 sharp 将上传的图片全部转成 webp 格式,并返回 webp 格式的链接。

服务的上传下载直接使用的COS-SDK,可以做有价值的参考。

项目仓库:github

需要注意,此服务需要开启开放接口服务

小程序中的调用代码如下:

Page({
    async onLoad() {
        wx.cloud.init({
            env: '云托管环境ID'
        })
        wx.chooseImage({
            count: 1,
            async success(res) {
                console.log('开始上传文件',res.tempFilePaths[0])
                const { fileID } = await wx.cloud.uploadFile({
                    cloudPath: 'test.png', // 这个文件地址可以换成动态的
                    filePath: res.tempFilePaths[0]
                })
                console.log('上传成功,开始转换',fileID)
                const info = await wx.cloud.callContainer({
                    path: '/made',
                    method: 'GET',
                    data:{
                        fileid:fileID
                    },
                    header: {
                        'X-WX-SERVICE': 'img',
                    }
                });
                console.log('转换完毕',info.data);
                if(info.data.code===0){
                    console.log('开始下载转换文件',info.data.fileid);
                    const downfile = await wx.cloud.downloadFile({
                        fileID:info.data.fileid
                    }) 
                    wx.previewImage({
                      urls: [downfile.tempFilePath],
                    })
                }
            }
        })
    }
})

# 总结

项目演示的图像处理环节可以换成其他任意的过程,对应的依赖和代码逻辑自己修正。

核心要点是服务端内正确下载文件,以及处理的文件正确上传并被小程序/H5访问。