微信小程序可以跨机型方便地调用设备的硬件,例如:摄像头、喇叭、蓝牙等。之前研究过蓝牙,但因为当时的接口限制和文档不多所以就没深潜;不过这个是个方向,有机会再展开吧。这次我们讲一下摄像头,功能大概是通过摄像头拍照后进行图片压缩后再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及上传。当然代码仅为核心功能代码,周边的功能就自己调试吧。