<template>
|
<view class="page wrap-fix">
|
<view class="canvas-wrap">
|
<!-- :style="{width: (widthScale * 100)+'%'; height:(heightScale * 100)+'%';}" -->
|
<canvas type="webgl" id="canvas"></canvas>
|
</view>
|
|
<!-- <view class="hint-words">提示:点击获取,会将摄像头资源转成贴图(需基础库3.4.4)</view> -->
|
|
<view class="wrap-option">
|
<view class="row">
|
<button type="primary" bindtap="getJpgImg">获取jpg图像</button>
|
<button type="primary" bindtap="getLog">开关调试log(时间戳)</button>
|
</view>
|
|
</view>
|
|
<view class="hint-img-wrap">
|
<view class="hint-img-box">
|
<image class="hint-img" v-if="jpgUrl !== ''" :src="jpgUrl" mode="aspectFit" />
|
</view>
|
</view>
|
|
|
</view>
|
</template>
|
|
<script>
|
import arBehavior from '@/components/behavior/behavior-ar'
|
import threeBehavior from '@/components/behavior/behavior-three'
|
export default {
|
mixins: [arBehavior, threeBehavior],
|
onLoad() {
|
// if (wx.offThemeChange) {
|
// wx.offThemeChange()
|
// }
|
// this.theme = wx.getSystemInfoSync().theme || 'light'
|
// if (wx.onThemeChange) {
|
// wx.onThemeChange(({
|
// theme
|
// }) => {
|
// this.theme = theme
|
// })
|
// }
|
this.getAuthSetting()
|
wx.getSetting({
|
success: (res) => {
|
console.log(res, 'rlsb');
|
},
|
})
|
},
|
data() {
|
return {
|
theme: 'light',
|
widthScale: 1 * 100, // canvas宽度缩放值
|
heightScale: 0.57 * 100, // canvas高度缩放值
|
jpgUrl: '',
|
}
|
},
|
methods: {
|
getAuthSetting() {
|
wx.getSetting({
|
success: (res) => {
|
console.log(res, 'rlsb');
|
if (!res.authSetting['scope.camera']) {
|
wx.showModal({
|
title: '请允许获取摄像头权限',
|
showCancel: false,
|
complete: (modalRes) => {
|
if (modalRes.confirm) {
|
wx.openSetting({
|
success: (settingRes) => {
|
if (!settingRes.authSetting[
|
'scope.camera']) {
|
this.getAuthSetting()
|
} else {
|
wx.navigateBack()
|
}
|
}
|
})
|
}
|
}
|
})
|
}
|
}
|
})
|
},
|
// 对应案例的初始化逻辑,由统一的 behavior 触发
|
init() {
|
// 初始化 Three.js,用于模型相关的渲染
|
this.initTHREE()
|
|
// 初始化 GL,基于 Three.js 的 Context,用于相机YUV渲染
|
this.initYUV()
|
|
// 初始化VK
|
// start完毕后,进行更新渲染循环
|
this.initVK();
|
|
this.useLoopLog = false;
|
this.imgIndex = 0;
|
},
|
initVK() {
|
// VKSession 配置
|
const session = this.session = wx.createVKSession({
|
track: {
|
face: {
|
mode: 1
|
},
|
},
|
version: 'v2',
|
gl: this.gl
|
});
|
|
session.start(err => {
|
if (err) return console.error('VK error: ', err)
|
|
console.log('@@@@@@@@ VKSession.version', session.version)
|
|
// VKSession EVENT resize
|
session.on('resize', () => {
|
this.calcCanvasSize();
|
})
|
|
// VKSession EVENT addAnchors
|
session.on('addAnchors', anchors => {})
|
|
// VKSession EVENT updateAnchors
|
session.on('updateAnchors', anchors => {
|
|
})
|
|
// VKSession removeAnchors
|
// 识别目标丢失时,会触发一次
|
session.on('removeAnchors', anchors => {
|
// console.log('removeAnchors', anchors)
|
});
|
|
|
console.log('ready to initloop')
|
// start 初始化完毕后,进行更新渲染循环
|
this.initLoop();
|
|
// 绘制双面,以及去掉清屏,用于显示yuv
|
this.renderer.state.setCullFace(this.THREE.CullFaceNone)
|
|
});
|
},
|
loop() {
|
|
// 获取 VKFrame
|
const frame = this.session.getVKFrame(this.canvas.width, this.canvas.height)
|
|
// 成功获取 VKFrame 才进行
|
if (!frame) {
|
return;
|
}
|
|
// 更新相机 YUV 数据
|
this.renderYUV(frame)
|
|
// 获取 VKCamera
|
const VKCamera = frame.camera
|
|
if (this.useLoopLog) {
|
// let transformStr = '';
|
// for (let i = 0; i < 16; i++)
|
// transformStr += VKCamera.transform[i] + ' ';
|
// console.log('VKCamera.transform', transformStr);
|
|
console.log('timeStamp', frame.timestamp);
|
|
|
let viewMatrixStr = '';
|
for (let i = 0; i < 16; i++)
|
viewMatrixStr += VKCamera.viewMatrix[i] + ' ';
|
// console.log('VKCamera.viewMatrix', viewMatrixStr);
|
if (this.preTimestamp && this.preTimestamp === frame.timestamp) {
|
if (this.preViewMatrixStr && this.preViewMatrixStr !== viewMatrixStr) {
|
console.log('preViewMatrixStr', this.preViewMatrixStr)
|
console.log('viewMatrixStr', viewMatrixStr)
|
console.log('Timestamp is same. But viewMatrix is not same');
|
}
|
}
|
this.preTimestamp = frame.timestamp;
|
this.preViewMatrixStr = viewMatrixStr;
|
}
|
|
},
|
getJpgImg() {
|
console.log('Function getJpgImg');
|
|
// 按需写入获取 jpg 的 大小 和质量
|
const width = 640;
|
const height = 480;
|
const quality = 90;
|
|
// 获取 VKFrame
|
const frame = this.session.getVKFrame(width, height)
|
|
// 成功获取 VKFrame 才进行
|
if (!frame) {
|
return;
|
}
|
|
console.log('getCameraJpgBuffer: ', width, height, quality)
|
|
const t1 = new Date().getTime()
|
const jpgBuffer = frame.getCameraJpgBuffer(width, height, quality);
|
const t2 = new Date().getTime()
|
|
console.log(`getCameraJpgBuffer cost ${t2 - t1}ms`)
|
|
// console.log('jpgBuffer', jpgBuffer);
|
|
const jpgUrl = this.saveLocalJPG(jpgBuffer, 'cameraJPG');
|
|
console.log('jpgUrl', jpgUrl)
|
|
this.setData({
|
'jpgUrl': jpgUrl
|
})
|
|
|
},
|
saveLocalJPG(bufferContent, name) {
|
var url = `${wx.env.USER_DATA_PATH}/${name + this.imgIndex + '.jpg'}`
|
|
const fs = wx.getFileSystemManager()
|
try {
|
// 存在即删除
|
const unlinkRes = fs.unlinkSync(url)
|
// console.log('unlinkSync', unlinkRes)
|
|
this.imgIndex++;
|
const newUrl = `${wx.env.USER_DATA_PATH}/${name + this.imgIndex + '.jpg'}`;
|
|
// console.log('write newUrl', newUrl)
|
// 写入,新图片
|
const writeRes = fs.writeFileSync(
|
newUrl,
|
bufferContent,
|
'utf8'
|
)
|
|
return newUrl
|
|
} catch (e) {
|
// 利用catch实现,此时,为新写入
|
try {
|
// console.log('write url', url)
|
|
// 写入
|
const writeRes = fs.writeFileSync(
|
url,
|
bufferContent,
|
'utf8'
|
)
|
} catch (e) {
|
console.error(e);
|
}
|
}
|
|
return url
|
},
|
getLog() {
|
console.log('Function getLog');
|
|
this.useLoopLog = !this.useLoopLog;
|
},
|
|
},
|
}
|
</script>
|
|
<style>
|
.canvas-wrap {
|
position: relative;
|
width: 100%;
|
background-color: #000;
|
}
|
|
.canvas-wrap #canvas {
|
position: absolute;
|
left: 0;
|
top: 0;
|
width: 100%;
|
height: 100%;
|
}
|
|
.hint-box {
|
position: absolute;
|
left: 0%;
|
top: 0%;
|
width: 0;
|
height: 0;
|
}
|
|
.hint-id {
|
position: absolute;
|
left: -6rpx;
|
right: -6rpx;
|
bottom: 100%;
|
color: #fff;
|
font-size: 20rpx;
|
line-height: 40rpx;
|
text-align: center;
|
text-overflow: ellipsis;
|
background-color: #07c160;
|
border-radius: 8rpx;
|
|
}
|
|
.wrap-fix {
|
position: absolute;
|
left: 0;
|
top: 0;
|
width: 100%;
|
height: 100%;
|
}
|
|
.hint-words {
|
position: absolute;
|
left: 20rpx;
|
top: 20rpx;
|
right: 20rpx;
|
padding: 10rpx 20rpx;
|
line-height: 40rpx;
|
text-align: center;
|
border-radius: 6rpx;
|
background-color: rgba(0, 0, 0, .3);
|
font-size: 26rpx;
|
color: #fff;
|
}
|
|
|
.hint-img-wrap {
|
position: absolute;
|
left: 25%;
|
bottom: 0%;
|
width: 50%;
|
height: 30%;
|
}
|
|
.hint-img-box {
|
position: absolute;
|
left: 5%;
|
top: 5%;
|
right: 5%;
|
bottom: 5%;
|
background-color: #fafafa;
|
border: 4rpx solid;
|
}
|
|
.hint-img {
|
position: absolute;
|
left: 4%;
|
top: 4%;
|
width: 92%;
|
height: 92%;
|
}
|
|
.wrap-option {
|
position: absolute;
|
left: 20rpx;
|
right: 0;
|
bottom: 30%;
|
height: 10%;
|
flex-direction: column;
|
display: flex;
|
}
|
|
.wrap-option .row {
|
flex: 1;
|
display: flex;
|
flex-direction: row;
|
text-align: center;
|
}
|
|
.wrap-option button {
|
flex: 1;
|
margin: 5rpx 20rpx 20rpx 0;
|
font-size: 30rpx;
|
line-height: 1.2;
|
}
|
</style>
|