1、业务场景
在小程序中,需要每隔0.5s获取获取一次Camera实时帧数据,转为base64
2、开始
(1)获取Camera 实时帧数据
// wxml
<camera device-position="{{device?'front':'back'}}" flash="off" binderror="error" style="width: 100%; height: 560rpx;" class="camera"></camera>
// js
let listener
page({
data: {
device: true,
speedMaxCount: 30
},
startTacking() {
var _that = this;
var count = 0;
const context = wx.createCameraContext();
if (!context.onCameraFrame) {
var message = '基础库 2.7.0 开始支持".';
wx.showToast({
title: message,
icon: 'none'
});
return;
}
listener = context.onCameraFrame(async function (res) {
// 每秒60帧,这里控制每0.5获取一次图片
if (count < _that.data.speedMaxCount) {
count++;
return;
}
count = 0;
_that.stopTacking()
// onCameraFrame 获取的是未经过编码的原始 RGBA 格式的图像数据,接下来转为图片
_that.changeDataToBase64(res)
});
// start
listener.start();
console.log('startTacking', 'listener is start');
},
stopTacking() {
if (listener) {
listener.stop();
}
},
onReady: function () {
this.startTacking();
},
})
(2)将获取到的原始图片数据转base64
onCameraFrame返回的数据格式如下图,将获取到的原始图片数据转base64
在js页面中引入upng
// js
const upng = require('../../../utils/upng/UPNG.js')
// js
changeDataToBase64() {
let pngData = upng.encode([frame.data], frame.width, frame.height)
let base64 = wx.arrayBufferToBase64(pngData)
// 拿到数据后的其他操作
}
主要问题:开发者工具测试时没有问题,真机测试,安卓机测试没有问题,但是ios机型转码时间特别长,基本在10s以上。这,,,都不用用户反馈,测试就过不了
借用 canvas 的 putImageData,添加到画布上,再转为临时文件,再将临时文件转为base64
小程序中canvasPutImageData写入data的数据类型为Uint8ClampedArray,但是获取的实时帧数据的data的数据类型为ArrayBuffer,所以需要先将ArrayBuffer的数据类型转为Uint8ClampedArray
// js
changeDataToBase64(frame) {
var data = new Uint8Array(frame.data);
var clamped = new Uint8ClampedArray(data);
let that = this
wx.canvasPutImageData({
canvasId: 'myCanvas',
x: 0,
y: 0,
width: frame.width,
height: frame.height,
data: clamped,
success(res) {
// 转换临时文件
console.log(res)
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: frame.width,
height: frame.height,
canvasId: 'myCanvas',
fileType: 'jpg',
destWidth: frame.width,
destHeight: frame.height,
// 精度修改
quality: 0.8,
success(res) {
// 临时文件转base64
wx.getFileSystemManager().readFile({
filePath: res.tempFilePath, //选择图片返回的相对路径
encoding: 'base64', //编码格式
success: res => {
// 保存base64
let base64 = res.data;
// 拿到数据后的其他操作
}
})
},
fail(res) {
console.log(res)
wx.showToast({
title: '图片生成失败,重新检测',
icon: 'none',
duration: 1000
})
// 测试的时候发现安卓机型,转为临时文件失败,这里从新获取帧数据,再转码就能成功,不知道为什么
that.startTacking()
}
}, that)
}
})
}
主要问题:开发者工具测试时没有问题,真机测试,ios时间明显缩短,大概在1s左右。安卓机时间也大概在1s左右,除了部分机型首次转为临时文件报错,只要再次获取帧数据,进行转码就没有问题了。
3、结束
写于2020年12月31日 17:27
2020就要结束了,我还没有男朋友
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论