小程序的智能裁剪接口应该怎么用
在小程序的服务端接口中,有一类是图像处理接口,其中有一个接口是让大家觉得用起来很头疼的,就是 aiCrop — 图片智能裁剪这个接口。
这个接口根据官方的描述,其能力是 “本接口提供基于小程序的图片智能裁剪能力。”,但是,根据文档中给出的结果,似乎也并没有返回图片的 Buffer 流,那么这个接口真正应该怎么用呢?背后又有什么坑呢?今天我就给你讲一讲。
前置条件
- 你需要已经注册好小程序,并开通小程序云开发(本次演示将基于小程序云开发制作)
业务流程
流程说明
- 用户侧选择图片,并生成临时文件路径(如果是网络图片,需要下载到本地,并修改云函数,改为直接传递 网络图片地址)
- 将图片上传的云存储中,并拿到 FileID
- 将 FileID 传递到云函数中,云函数获取到对应的临时 URL
- 将临时文件 URL 传递到微信的 AI 剪切接口
- AI 接口将裁剪结果返回到云函数
- 云函数将裁剪结果返回到小程序
- 小程序基于返回结果进行渲染。
服务端代码
这里我们创建一个云函数来完成图片的裁剪,你需要创建一个新的云函数,其中index.js
的代码如下
// index.js
const cloud = require('wx-server-sdk')
cloud.init()
// 云函数入口函数
exports.main = async (event, context) => {
let fileId = event.file;
// 获取文件的临时连接
let tempUrl = await cloud.getTempFileURL({
fileList: [fileId]
})
let newUrl = tempUrl.fileList[0].tempFileURL;
// 对图片进行裁剪
let cropResult = await cloud.openapi.img.aiCrop({
imgUrl:newUrl,
ratios:'1,2.35,0.5,0.25,3.25'//裁剪比例
})
return cropResult
}
以及在该函数目录下创建一个 config.json
文件,内容如下
{
"permissions": {
"openapi": [
"img.aiCrop"
]
}
}
这样就完成了云函数部分的内容。
上面这段代码帮助我们获取 FileID 对应的文件临时路径,并将其传递给微信接口进行调用。
小程序端调用代码
在小程序端,我们主要是选择文件,将其上传到云端,并调用云函数进行裁剪,在取得返回值后在小程序端进行渲染。
小程序的页面 JS 代码如下
Page({
/**
* 由于此数据仅在逻辑层使用,因此定义一个tempData 进行存储
*/
tempData:{
path:null,
},
onClick() {
/**
* 选择文件
*/
wx.chooseImage({
success: res => {
/**
* 获取文件路径,并传递给 tempData
*/
let file = res.tempFiles[0].path
this.tempData.path = file
console.log("[info]:开始上传文件")
/**
* 上传文件到云存储
*/
wx.cloud.uploadFile({
filePath: file,
cloudPath: "test.jpg"
}).then(res => {
/**
* 调用云函数
*/
console.log("[info]:开始调用云端裁剪")
wx.cloud.callFunction({
name: "aicrop",
data: {
file: res.fileID
}
}).then(res => {
/**
* 调用裁剪
*/
console.log("[info]:云端裁剪成功 ", res)
this.crop(res.result);
}).catch(err => {
console.error("[error]:函数调用错误", err)
})
}).catch(err => {
console.error("[error]:文件上传错误", err)
})
},
fail: err => {
console.error("[error]:文件选择错误", err)
}
})
},
crop(cropOps) {
/**
* 获取 Context
*/
let ctx = wx.createCanvasContext('aiCrop', this);
/**
* 判断是否成功裁剪
*/
if (cropOps.results.length == 0) {
return
}
/**
* 计算裁剪的值
*/
let crop = cropOps.results[0];
let width = crop.cropRight - crop.cropLeft
let height = crop.cropBottom - crop.cropTop
/**
* 绘制图像
*/
ctx.drawImage(this.tempData.path, crop.cropLeft, crop.cropTop, width, height, 0, 0, 300, 300);
ctx.draw()
}
})
对应页面的 WXML 页面结构如下
<button bindtap="onClick">Crop MY IMAGE</button>
<canvas canvas-id="aiCrop" style="width:300px;height:300px;"></canvas>