社区/学习指南/小程序·云开发高级教程

图像处理和OCR

云调用有些接口属于 AI 服务的范畴,比如借助于人工智能来进行智能裁剪、扫描条码/二维码、图片的高清化等图像处理和识别银行卡、营业执照、驾驶证、身份证、印刷体、驾驶证等 OCR,有了这些接口我们也能在小程序里使用人工智能了。接下来我们以小程序的条码/二维码识别和识别印刷体为例来介绍一下云调用。

13.3.1 图像处理

使用开发者工具新建一个云函数,如 scancode,然后在 config.json 里添加 img.scanQRCode 云调用的权限,使用 npm install 安装依赖之后,上传并部署所有文件(此时也会更新权限)。


{

  "permissions": {

    "openapi": [

      "img.scanQRCode"

    ]

  }

}

然后再在 index.js 里输入以下代码,注意cloud.openapi.img.scanQRCode方法和img.scanQRCode权限的对应写法,不然会报 604100 的错误。

const cloud = require("wx-server-sdk");

cloud.init({
  env: cloud.DYNAMIC_CURRENT_ENV,
});

exports.main = async (event, context) => {
  try {
    const result = await cloud.openapi.img.scanQRCode({
      imgUrl:
        "https://tcb-1251009918.cos.ap-guangzhou.myqcloud.com/demo/qrcodetest.png", //注意二维码必须是条码/二维码,不能是小程序码
    });

    return result;
  } catch (err) {
    console.log(err);

    return err;
  }
};

调用该云函数之后,返回的 result 对象里包含 result 对象,在 codeResults 的 data 里可以得到二维码里包含的内容。


codeResults: [{

  data: "使用云开发来开发微信小程序可以免费。。。",

  pos: {leftTop: {…}, rightTop: {…}, rightBottom: {…}, leftBottom: {…}},typeName: "QR_CODE"}]

errCode: 0

errMsg: "openapi.img.scanQRCode:ok"

imgSize: {w: 260, h: 260}

13.3.2 OCR 人工智能识别

使用开发者工具新建一个云函数,如 ocrprint,然后在 config.json 里添加 ocr.printedText 云调用的权限,使用 npm install 安装依赖之后,上传并部署所有文件(此时也会更新权限)。


{

  "permissions": {

    "openapi": [

      "ocr.printedText"

    ]

  }

}

调用该云函数之后,返回的 result 对象里包含 result 对象,在 codeResults 的 data 里可以得到二维码里包含的内容。

const cloud = require("wx-server-sdk");

cloud.init({
  env: cloud.DYNAMIC_CURRENT_ENV,
});

exports.main = async (event, context) => {
  try {
    const result = await cloud.openapi.ocr.printedText({
      imgUrl:
        "https://tcb-1251009918.cos.ap-guangzhou.myqcloud.com/demo/ocrprint.png",
    });

    console.log(result);

    return result;
  } catch (err) {
    console.log(err);

    return err;
  }
};

调用该云函数之后,返回的 result 对象里包含 result 对象,在的 items 里可以返回图片包含的文字内容。


items: Array(4)

0: {text: "JavaScript入门", pos: {…}}

1: {text: "JavaScript是目前世界上最流行的编程语言之一,它也是小程序开发最重要的基础语言。要做出一个功能复杂的小程序,除了需要掌握JavaScript的基本语", pos: {…}}

2: {text: "法,还要了解如何使用JavaScript来操作小程序(通过API接口)", pos: {…}}

3: {text: "过API接口)。", pos: {…}}

13.3.3 图像处理拓展能力

图片是小程序非常重要的元素,尤其是旅游照片、社交图片、电商产品图片、相册类小程序、媒体图文等,图片的加载速度、清晰度、图片的交互、图片效果的处理以及图片加载的 CDN 消耗都是一个不得不需要去关注的问题。而云开发图像处理拓展能力结合云存储则可以非常有效的解决很多问题。

强烈建议所有有图片处理需求的用户都应该安装图像处理拓展能力,这个能力大大弥补和增强了云存储在图片处理能力,尤其是图片按照需求的规格进行缩放可以大大减少 CDN 的消耗以及图片的加载速度以及我们可以按照不同的业务场景使用快速缩略模板,而这一切的操作和云存储的结合都是非常实用且易用的。

1、图像处理能力介绍

云开发图像处理能力结合的是腾讯云数据万象的图片解决方案,图像处理提供多种图像处理功能,包含智能裁剪、无损压缩、水印、格式转换等,图像处理拓展能力所包含的功能非常丰富,使用如下图片处理的费用是按量计费的,计费周期为月,10TB 以内免费,超出 10TB,按 0.025 元/GB 来计费,省事而便宜:

  • 缩放:等比缩放、设定目标宽高缩放等多种方式;

  • 裁剪:普通裁剪、缩放裁剪、内切圆、人脸智能裁剪;

  • 旋转:普通旋转、自适应旋转;

  • 格式转换:jpg、bmp、gif、png、webp、yjpeg 格式转换,gif 格式优化,渐进显示功能;

  • 质量变换:针对 JPG 和 WEBP 图片进行质量变换;

  • 高斯模糊:对图片进行模糊处理;

  • 锐化:对图片进行锐化处理;

  • 图片水印:提供图片水印处理功能;

  • 文字水印:提供实时文字水印处理功能;

  • 获取图片基本信息:查询图片基本信息,包括格式、长、宽等;

  • 获取图片 EXIF:查询图片 EXIF 信息,如照片的拍摄参数、缩略图等;

  • 获取图片主色调:获取图片主色调信息;

  • 去除元信息:去除图片元信息,减小图像体积;

  • 快速缩略模板:快速实现图片格式转换、缩略、剪裁等功能,生成缩略图;

  • 管道操作符:对图片按顺序进行多种处理

当我们在腾讯云云开发网页控制台(注意要使用微信公众号的方式登录)添加完图像处理的拓展能力之后,我们可以在腾讯云的数据万象存储桶里看到云开发的云存储,而关于图像处理能力的深入使用,也可以参考腾讯云数据万象的技术文档

在小程序云开发里使用图像处理能力的方法有三种:

  • 图像地址的拼接,只需要在图片的下载地址 url 里拼接一些简单的参数(API 管道操作符),就能够使用到图像处理的能力,非常方便易用,这个不会把图片处理的结果存储到云存储,不会占用云存储的空间;在获取图片基本信息、获取图片 EXIF、获取图片主色调等方面非常方便;

  • 在前端(小程序端)做持久化图像处理,支持有结果图输出的处理操作,也就是我们可以把缩放、裁剪、格式转换、质量变换等处理之后的图片存储到云存储方便以后使用;

  • 在云函数端做持久化图像处理,支持有结果图输出的处理操作

1、图像地址的拼接

在了解图像处理能力之前,我们需要先了解一下云存储文件的 fileID、下载地址以及下载地址携带的权限参数 sign(图像处理能力的参数拼接就是基于下载地址的),如下图所示:

在安装了图像处理拓展能力的情况下,我们可以直接拿云存储的下载地址进行拼接,拼接之后的链接我们既可以在小程序里使用,也可以用于图床,比如原始图片下载地址为:


https://786c-xly-xrlur-1300446086.tcb.qcloud.la/hehe.jpg?sign=b8ac757538940ead8eed4786449b4cd7&t=1591752049

而相关的图像处理能力的拼接案例如下,具体的操作可以看技术文档,实际的效果,可以复制粘贴链接到浏览器或小程序里体验(换成自己的地址),注意拼接方式就是在下载地址后面加了一个&imageMogr2/thumbnail/!20p(注意这里由于已经有了一个 sign 参数,所以拼接时用的是$,不能写成?,否则不会生效),直接就可以啦,非常易用:


//将图片等比例缩小到原来的20%

https://786c-xly-xrlur-1300446086.tcb.qcloud.la/hehe.jpg?sign=b8ac757538940ead8eed4786449b4cd7&t=1591752049&imageMogr2/thumbnail/!20p

后面为了方便,我们将https://786c-xly-xrlur-1300446086.tcb.qcloud.la/hehe.jpg?sign=b8ac757538940ead8eed4786449b4cd7&t=1591752049简写为 download_url:


//缩放宽度,高度不变,下面案例为宽度为原图50%,高度不变

download_url&imageMogr2/thumbnail/!50px


//缩放高度,宽度不变,下面案例为高度为原图50%,宽度不变

download_url&imageMogr2/thumbnail/!x50p


//指定目标图片的宽度(单位为px),高度等比压缩,注意下面的是x,不是px,p与x在拼接里代表着不同的意思

download_url&imageMogr2/thumbnail/640x


//指定目标图片的高度(单位为px),宽度等比压缩:

download_url&imageMogr2/thumbnail/x355


//限定缩略图的宽度和高度的最大值分别为 Width 和 Height,进行等比缩放

download_url&imageMogr2/thumbnail/640x355


//限定缩略图的宽度和高度的最小值分别为 Width 和 Height,进行等比缩放

download_url&imageMogr2/thumbnail/640x355r


//忽略原图宽高比例,指定图片宽度为 Width,高度为 Height ,强行缩放图片,可能导致目标图片变形

download_url&imageMogr2/thumbnail/640x355!


//等比缩放图片,缩放后的图像,总像素数量不超过 Area

download_url&imageMogr2/thumbnail/150000@


//取半径为300,进行内切圆裁剪

download_url&imageMogr2/iradius/300


//取半径为100px,进行圆角裁剪

download_url&imageMogr2/rradius/100


//顺时针旋转90度

download_url&imageMogr2/rotate/90


//将jpg格式的原图片转换为 png 格式

download_url&imageMogr2/format/png


//模糊半径取8,sigma 值取5,进行高斯模糊处理

download_url&imageMogr2/blur/8x5


//获取图片的基础信息,返回的是json格式,我们可以使用https请求来查看图片的format格式,width宽度、height高度,size大小,photo_rgb主色调

download_url&imageInfo

2、小程序端持久化图像处理

当我们希望把缩放、裁剪、旋转、格式变换等图像处理的结果(也就是处理之后的图片)存储到云存储,这个就叫做持久化图像处理,在安装了图像处理能力之后,我们也可以在小程序端做图像处理。

当用户把原始图片上传到小程序端时,我们需要对该图片进行一定的处理,比如图片过大就对图片进行裁剪缩小;比如图片需要进行一定的高斯模糊、旋转等处理,这些虽然在图像处理之前,也是可以使用 js 来做的,但是小程序端图像处理的效果并没有那么好或者过于复杂,使用图像处理的拓展能力就非常实用了。

在小程序端构建图像拓展依赖

首先在开发者工具小程序根目录(一般为 miniprogram),右键“在终端中打开”,然后在终端里输入以下代码,也就是在小程序端安装图像拓展依赖,安装完时,我们就可以在 miniprogram 文件夹下看到 node_modules:


npm install --save @cloudbase/extension-ci-wxmp@latest

然后点击开发者工具工具栏里的工具-构建 npm,构建成功之后,就可以在 miniprogram 文件夹下看到 minprogram_npm 里有@cloubase 文件夹,里面有 extension-ci-wxmp,说明图像拓展依赖就构建完成。

在小程序端进行图像处理

使用开发者工具新建一个 imgprocess 的页面,然后在 imgprocess.wmxl 里输入如下代码,我们新建一个 button 按钮:


<button bindtap="imgprocess">处理图片</button>

然后再在 imgprocess.js 的 Page()函数的上面(外面)引入图像处理依赖,代码如下:

const extCi = require("./../../miniprogram_npm/@cloudbase/extension-ci-wxmp");

然后再在 imgprocess.js 的 Page()函数的里面写一个 imgprocess 的事件处理函数,点击 button 之后会先执行 readFile()函数,也就是获取图片上传到小程序临时文件的结果(是一个对象),然后再调用 imageProcess()函数,这个函数会对图片进行处理,图片会保存为tcbdemo.jpg,而处理之后的图片会保存为 image_process 文件夹下的 tcbdemo.png,相当于保存了两张图片:


async imgprocess(){

  const readFile = async function() {

    let res = await new Promise(resolve=>{

        wx.chooseImage({

            success: function(res) {

                let filePath = res.tempFilePaths[0]

                let fm = wx.getFileSystemManager()

                fm.readFile({

                    filePath,

                    success(res){

                        resolve(res)

                    }

                })

            }

        })

    })

    return res

  }



  let fileResult = await readFile(); //获取图像的临时文件上传结果

  const fileContent = fileResult.data  //获取上传到临时文件的图像,为Uint8Array或Buffer格式


  async function imageProcess() {

    extCi.invoke({

      action: "ImageProcess",

      cloudPath: "tcbdemo.jpg", // 图像在云存储中的路径,有点类似于wx.cloud.uploadFile接口里的cloudPath,上传的文件会保存为云存储根目录下的hehe.jpg

      operations: {

        rules: [

          {

            fileid: "/image_process/tcbdemo.png", //将图片存储到云存储目录下的image_process文件夹里,也就是我们用image_process存储处理之后的图片

            rule: "imageMogr2/format/png", // 处理样式参数,我们可以在这里写图片处理的参数拼接

          }

        ]

      },

      fileContent

    }).then(res => {

        console.log(res);

    }).catch(err => {

        console.log(err);

    })

  }

  await imageProcess()

}

  • 可能你的开发者工具会报以下错误:https://786c-xly-xrlur-1300446086.pic.ap-shanghai.myqcloud.com 不在以下 request 合法域名列表中,请参考文档:https://developers.weixin.qq.com/miniprogram/dev/framework/ability/network.html,这个要按照参考文档将链接加入到合法域名当中,不然不会生成图片;

  • action是操作类型,它的值可以为:ImageProcess 图像处理,DetectType 图片安全审核(后面会介绍),WaterMark 图片忙水印、DetectLabel 图像标签等。

  • operations是图像处理参数,尤其是 rule 和我们之前 url 的拼接是一致的,比如imageMogr2/blur/8x5imageMogr2/rradius/100等参数仍然有效。

上面函数里的 fileContent 不是必要的,也就是说我们可以不在小程序端上传图片,而是直接修改云存储里面已有的图片,并将图片处理后的照片保存,这种情况代码可以写成如下:


async imgprocess(){

  extCi.invoke({

    action: "ImageProcess",

    cloudPath: "tcbdemo.jpg", // 会直接处理这张图片

    operations: {

      rules: [

        {

          fileid: "/image_process/tcbdemo.png",

          rule: "imageMogr2/format/png", // 处理样式参数,与下载时处理图像在url拼接的参数一致

        }

      ]

    },

  }).then(res => {

      console.log(res);

  }).catch(err => {

      console.log(err);

  })

}

3、云函数端持久化图像处理

在云函数端的处理和小程序端的处理,使用的方法大体上是一致的,不过云函数的处理图片的场景和小程序端处理图片的场景会有所不同,小程序端主要用于当用于上传图片时就对图片进行处理,云函数则主要用于从第三方下载图片之后进行处理或者对云存储里面的图片进行处理(比如使用定时触发器对云存储里指定文件夹的图片进行处理)。不建议把图片传输到云函数端再来对图片进行处理。

使用开发者工具新建一个 imgprocess 的云函数,然后在 package.json 里添加 latest 最新版的@cloudbase/extension-ci,并右键云函数目录选择在终端中打开输入命令 npm install 安装依赖:


"dependencies": {

  "wx-server-sdk": "latest",

  "@cloudbase/extension-ci": "latest"

}

然后再在 index.js 里输入以下代码,代码的具体含义可以参考小程序端的内容讲解:

const cloud = require("wx-server-sdk");

cloud.init({
  env: cloud.DYNAMIC_CURRENT_ENV,
});

const extCi = require("@cloudbase/extension-ci");

cloud.registerExtension(extCi);

async function process() {
  try {
    const opts = {
      rules: [
        {
          fileid: "/image_process/tcbdemo.jpeg",

          rule: "imageMogr2/format/png",
        },
      ],
    };

    const res = await app.invokeExtension("CloudInfinite", {
      action: "ImageProcess",

      cloudPath: "tcbdemo.jpg",

      fileContent,

      operations: opts,
    });

    console.log(res);

    return res;
  } catch (err) {
    console.log(err);
  }
}

本文出自 李东bbsky