小程序的智能裁剪接口应该怎么用
发布于 5 年前 作者 leichao 5302 次浏览 来自 分享

在小程序的服务端接口中,有一类是图像处理接口,其中有一个接口是让大家觉得用起来很头疼的,就是 aiCrop — 图片智能裁剪这个接口。

这个接口根据官方的描述,其能力是 “本接口提供基于小程序的图片智能裁剪能力。”,但是,根据文档中给出的结果,似乎也并没有返回图片的 Buffer 流,那么这个接口真正应该怎么用呢?背后又有什么坑呢?今天我就给你讲一讲。

前置条件

  • 你需要已经注册好小程序,并开通小程序云开发(本次演示将基于小程序云开发制作)

业务流程

流程说明

  1. 用户侧选择图片,并生成临时文件路径(如果是网络图片,需要下载到本地,并修改云函数,改为直接传递 网络图片地址)
  2. 将图片上传的云存储中,并拿到 FileID
  3. 将 FileID 传递到云函数中,云函数获取到对应的临时 URL
  4. 将临时文件 URL 传递到微信的 AI 剪切接口
  5. AI 接口将裁剪结果返回到云函数
  6. 云函数将裁剪结果返回到小程序
  7. 小程序基于返回结果进行渲染。

服务端代码

这里我们创建一个云函数来完成图片的裁剪,你需要创建一个新的云函数,其中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>
1 回复

白大神能否出一篇云开发图片上传顺序的文章,wx.cloud.uploadFile异步返回值顺序错乱,我相信不止我一人遇到了这个问题,社区里确实无人应答。

回到顶部