社区/学习指南/微信云开发高级教程

图像处理

11.4.1 二维码 qrcode

在移动互联网时代,二维码是一个非常重要的入口,有时候我们需要将一些文本、网址乃至文件、图片、名片等信息放置到一个小小的二维码里,让用户可以通过手机扫码的方式来获取传递的信息。云函数也可以借助于第三方模块,比如 node-qrcode 来创建二维码。

技术文档:node-qrcode Github 地址

使用开发者工具,创建一个云函数,如 qrcode,然后在 package.json 增加 qrcode 最新版 latest 的依赖并用 npm install 安装:


"dependencies": {

    "qrcode": "latest"

  }

然后再在 index.js 输入如下代码,这里会先将创建的二维码写入到临时文件夹,然后再用 fs.createReadStream 方法读取图片,上传到云存储,还是以云存储为过渡,实现文件由服务端到小程序端的一个操作。

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

const fs = require("fs");

const QRCode = require("qrcode");

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

exports.main = async (event, context) => {
  //text为二维码里包含的内容,将创建的二维码图片先存储到/tmp临时文件夹里,命名为qrcode.png

  const text = "二维码里的有腾讯云云开发";

  await QRCode.toFile(
    "/tmp/qrcode.png",
    text,
    {
      color: {
        dark: "#00F", // 蓝点

        light: "#0000", // 透明底
      },
    },
    function (err) {
      if (err) throw err;

      console.log("done");
    }
  );

  //读取存储到/tmp临时文件夹里的二维码图片并上传到云存储里,返回fileID到小程序端

  const fileStream = await fs.createReadStream("/tmp/qrcode.png");

  return await cloud.uploadFile({
    cloudPath: "qrcode.jpg",

    fileContent: fileStream,
  });
};

执行云函数之后就能在云存储里看到我们生成的二维码图片 qrcode.jpg 了。如果想要深度定制更加符合你要求的二维码,可以去翻阅上面给的技术文档链接。

11.4.2 Sharp 高速图像处理库

sharp 是一个高速图像处理库,可以很方便的实现图片编辑操作,如裁剪、格式转换、旋转变换、滤镜添加、图片合成(如添加水印)、图片拼接等,支持 JPEG, PNG, WebP, TIFF, GIF 和 SVG 格式。在云函数端使用 sharp 来处理图片,而云存储则可以作为服务端和小程序端来传递图片的桥梁。

由于图片处理是一件非常消耗性能的事情,不仅会对云函数的内存有要求,也可能会造成云函数的超时,以下只是研究使用云函数来处理图片的可行性,大家在实际开发中不要这么处理,建议使用云开发的拓展能力来对图像进行处理,功能更加强大(在后面的章节里,我们会介绍)。

技术文档:sharp 官方技术文档

使用开发者工具,创建一个云函数,如 sharp,然后在 package.json增加 node-qrcode 最新版 latest 的依赖,并右键云函数目录选择在终端中打开输入命令 npm install 安装依赖:


"dependencies": {

    "sharp": "latest"

  }

然后再在 index.js 输入如下代码,这里我们假定图片来源是云存储,我们需要先下载图片,然后用 sharp 对图片进行处理,处理完之后再把图片传回云存储。

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

const fs = require("fs");

const path = require("path");

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

const sharp = require("sharp");

exports.main = async (event, context) => {
  //这里换成自己的fileID,也可以在小程序端上传文件之后,把fileID传进来event.fileID

  const fileID =
    "cloud://xly-xrlur.786c-xly-xrlur-1300446086/1572315793628-366.png";

  //要用云函数处理图片,需要先下载图片,返回的图片类型为Buffer

  const res = await cloud.downloadFile({
    fileID: fileID,
  });

  const buffer = res.fileContent;

  //sharp对图片进行处理之后,保存为output.png,也可以直接保存为Buffer

  await sharp(buffer).rotate().resize(200).toFile("output.png");

  // 云函数读取模块目录下的图片,并上传到云存储

  const fileStream = await fs.createReadStream(
    path.join(__dirname, "output.png")
  );

  return await cloud.uploadFile({
    cloudPath: "sharpdemo.jpg",

    fileContent: fileStream,
  });
};

也可以让 sharp 不需要先 toFile 转成图片,而是直接转成 Buffer,这样就可以直接作为参数传给 fileContent 上传到云存储,如:

const buffer2 = await sharp(buffer).rotate().resize(200).toBuffer();

return await cloud.uploadFile({
  cloudPath: "sharpdemo2.jpg",

  fileContent: buffer2,
});

需要说明的是 sharp 有一定的前置条件,Node.js 的版本需要是 v10.13.0+,以及云函数所在的服务器配置了 libvips binaries,目前云开发的云函数不太支持,未来云开发会升级 Nodejs 的版本。关于图片处理的库,我们也可以去 Github awesome-nodejs 项目里去翻翻看有没有其他合适的解决方案,不过更加推荐的是使用云开发的图像处理拓展能力,更或者说强烈建议所有有图片处理需求的用户都应该安装图像处理拓展能力

本文出自 李东bbsky