<template>
<view class="con">
<camera
device-position="back"
frame-size="small"
resolution="high"
@initdone="startListener"
@stop="endListener"
@error="error"
mode="scanCode"
class="camera"
></camera>
</view>
</template>
<style lang="scss" scoped>
.con {
width: 100vw;
height: 100vh;
.camera {
width: 100%;
height: calc(920rpx + 180rpx);
}
}
</style>
红色的框根据业务要求调整吧,帧数和分辨率越高最终生成的BASE64越大(小程序里BASE64压缩我还没有实现,有大佬实现的可以留个路子,蟹蟹).蓝色框指定camera为scanCode(扫码模式)
<script>
export default {
data() {
return {
video
context: null,
listener: null,
processing_flag: false
}
},
methods: {
startListener() {
let that = this
console.log('初始化完成********************************************')
//camera回调
if (this.context == null && this.listener == null) {
const context = uni.createCameraContext()
const listener = context.onCameraFrame(async (frame) => {
if (that.processing_flag == false) {
that.processing_flag = true
const unit8Arr = new Uint8ClampedArray(frame.data.slice(0)) //数组拷贝,因为frame是个共享地址
const thisFrameWidth = frame.width
const thisFrameHeight = frame.height
//计算rgb图
const rgb = new Uint8Array(thisFrameWidth * thisFrameHeight * 3)
that.rgba2rgb(unit8Arr, rgb, thisFrameWidth, thisFrameHeight)
const base64Data = that.btoa(rgb)
console.log(base64Data, '<===============base64Data ')
// TODO 接口请求.......
// await xxxxxxx
that.processing_flag = false
}
})
this.context = context
this.listener = listener
}
this.listener.start()
},
endListener() {
this.listener && this.listener.stop()
this.context = null
},
error(e) {
console.log(e.detail)
},
rgba2rgb(rgba, rgb, width, height) {
let x
let y
let index
let rgba_index
let rgb_index
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
index = y * width + x
rgba_index = index * 4
rgb_index = index * 3
rgb[rgb_index] = rgba[rgba_index]
rgb[rgb_index + 1] = rgba[rgba_index + 1]
rgb[rgb_index + 2] = rgba[rgba_index + 2]
}
}
},
btoa(gray) {
const b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
var bitmap
var a
var b
var c
var result = ''
var i = 0
var rest = gray.length % 3 // To determine the final padding
for (; i < gray.length; ) {
if ((a = gray[i++]) > 255 || (b = gray[i++]) > 255 || (c = gray[i++]) > 255) {
throw new TypeError(
"Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range."
)
}
bitmap = (a << 16) | (b << 8) | c
result +=
b64.charAt((bitmap >> 18) & 63) +
b64.charAt((bitmap >> 12) & 63) +
b64.charAt((bitmap >> 6) & 63) +
b64.charAt(bitmap & 63)
}
// If there's need of padding, replace the last 'A's with equal signs
return rest ? result.slice(0, rest - 3) + '==='.substring(rest) : result
},
}
}
标签:uniapp,const,context,index,AI,微信,listener,rgb,rgba
From: https://blog.csdn.net/weixin_47675705/article/details/142484623