微信小程序摄像头压缩图片为Base64

2022-02-08 15:54:28 浏览数 (2)

微信小程序可以跨机型方便地调用设备的硬件,例如:摄像头、喇叭、蓝牙等。之前研究过蓝牙,但因为当时的接口限制和文档不多所以就没深潜;不过这个是个方向,有机会再展开吧。这次我们讲一下摄像头,功能大概是通过摄像头拍照后进行图片压缩后再Base64上传到服务器。

第一步:打开摄像头和即时显示画面

首先要显示画面必须要在WXML文件指定一个区域:

代码语言:javascript复制
<!-- 相机组件,放在UI最底层展示相机内容 -->
<camera frame-size="medium"
        bindinitdone="onCameraInit"
        mode="normal"
        device-position="back"
        resolution="high"
        flash="off"/>
<!-- canvas组件,用于图片压缩,位置在屏幕外,不可见 -->
<canvas type="2d"
        id="capture"
        style="width: 1px; height: 1px;"/>

然后在JS调用摄像进行播放,对摄像头进行监听。

代码语言:javascript复制
const query = wx.createSelectorQuery();
query.select('#capture')
    .fields({node: true})
    .exec((res) => {
        const canvas = res[0].node;
        //设置canvas内部尺寸为480*640,frame-size="medium"的设置下相机帧大多是480*640
        canvas.width = 480;
        canvas.height = 640;
        this.canvas = canvas;
    });

let cameraContext = wx.createCameraContext();
let listener = cameraContext.onCameraFrame(frame => {
    if (!this.canvas) return;
    let canvas = this.canvas;
    //如果尺寸不匹配,就修改canvas尺寸以适应相机帧
    if (canvas.width !== frame.width || canvas.height !== frame.height) {
        canvas.width = frame.width;
        canvas.height = frame.height;
    }

    //TODO 在这里保存frame对象,以便在需要的时候进行下一步压缩图片、发起CRS请求。不要在onCameraFrame回调中直接处理。
});
listener.start();

第二步:获得图像后进行压缩

这里可以搜索一下upng.js这个第三方的js,当然这个需要依赖pako包,我们这次不用。。

代码语言:javascript复制
let context = this.canvas.getContext('2d');
let ctxImageData = context.createImageData(frame.width, frame.height);
ctxImageData.data.set(new Uint8ClampedArray(frame.data)); //复制相机帧内容到imageData
context.putImageData(ctxImageData, 0, 0); //将imageData画到canvas上
let dataUrl = this.canvas.toDataURL("image/jpeg", 0.7); //使用toDataURL方法将相机帧压缩为JPEG,质量70%
let base64 = dataUrl.substr(23); //去除dataURL头,留下文件内容的base64

第三步:数据发起请求

代码语言:javascript复制
const params = {
    image: base64,
    notracking: "true",
    appId: "云识别库的 CRS AppId",
};

// https://云识别库的Client-end URL>/search 在未识到目标时,HTTP状态码为404。
return new Promise((resolve, reject) => {
    wx.request({
        url: "URL",
        method: 'post',
        data: params,
        header: {
            'Authorization': "使用APIKey APISecret生成的Token",
            'content-type': 'application/json'
        },
        success: res => resolve(res.data), //处理方法见下
        fail: err => reject(err),
    });
});

当然也可以

代码语言:javascript复制
  wx.request({
          url: "URL",
          method: 'POST',
          header: {
            'content-type': 'application/json' // 默认值
          },
          data: {
            "image": base64,
            "top_num": 1,
            "threshold": 0.01
          },
          success: function (res) {        
            
          },
          fail: function (res) {
            console.log(res);
          },
          complete: function (res) {
            //  that.setData({ sendload: false });
          }
        })

这样就进行简单的摄像头获得的图片进行压缩和转为BASE64及上传。当然代码仅为核心功能代码,周边的功能就自己调试吧。

0 人点赞