一.预期效果:
打开相机,在相机上增加虚拟的相框
【图一】
二.思路
将【图一】看作是一个页面或者一个组件,小程序自带【camera】标签,使用camera去画相机。
我做了两套,一套是以页面的形式,一套是组件,考虑到需要关闭这个页面,以及拍照后回传拍好的图片,最终采用了组件的形式作为封装。
三.代码
<view class="custom-camera">
<camera mode="normal" device-position="back" flash="off" :style="{ height: cameraHeight + 'px' }">
<cover-view class="controls" style="width: 100%;height: 100%;">
<cover-image class="bill-border" src="https://img-blog.csdnimg.cn/20210126144225906.png" />
</cover-view>
</camera>
<view class="bottom">
<view class="wrap">
<view class="back" @click="back">取消</view>
<view @click="takePhoto">
<image class="ok-icon"
src="https://img95.699pic.com/xsj/0y/mi/31.jpg%21/fw/700/watermark/url/L3hzai93YXRlcl9kZXRhaWwyLnBuZw/align/southeast">
</image>
</view>
<view @click="handleChooseCamera">
相册
</view>
</view>
</view>
</view>
// 从相册选取
const handleChooseCamera = async () => {
.chooseMedia({
count: 1,
mediaType:1,
sourceType: 3,
cameraType:1,
maxDuration:60,
})
.then((res) => {
console.log(res, "res=======");
})
.catch((err) => {
return err;
});
}
// 拍照
const takePhoto = () => {
cameraContext.value.takePhoto({
quality: 'normal',
success: (res: any) => {
console.log(res, '成功res');
},
fail: (err: any) => {
uni.showToast({
title: '拍照失败,请检查系统是否授权',
icon: 'none',
duration: 1200
})
}
})
}
四.自定义弹出框,切勿使用wx自带
<template>
<view class="cameraPopupWrap">
<uni-popup ref="cameraPopupRef" class="cameraPopup" :is-mask-click="false" type="bottom"
border-radius="10px 10px 0 0" :safe-area="false">
<view class="camera-box">
<view class="item" @click="handlechooseType('1')">拍摄
</view>
<view class="item" @click="handlechooseType('2')">
从手机相册选择
</view>
<view class="item cancel" @click="triggerPopupHide">
取消
</view>
</view>
</uni-popup>
</view>
</template>
采用自定义弹出框,为了区分选择相册还是采用拍摄,如果拍摄则调用自定义组件 ,
const cameraPopupRef = ref(null)
const emits = defineEmits(['changeType'])
const triggerPopupShow = () => {
// @ts-ignore
cameraPopupRef.value?.open()
}
const triggerPopupHide = () => {
// @ts-ignore
cameraPopupRef.value?.close()
}
const handlechooseType = (type = '') => {
emits('changeType', type)
}
defineExpose({
triggerPopupShow,
triggerPopupHide
})
const handleChangeType = async (type: string = '') => {
console.log('type::', type);
if (type === '1') {
console.log('拍摄');
isPhotoShow.value = true //如果选择拍摄,则让拍摄相机组件展示
// @ts-ignore
billCarmerRef.value.triggerPopupHide()
}
if (type === '2') {
console.log('相册');// 直接调用wx自带,采用相册选择功能
// @ts-ignore
billCarmerRef.value.triggerPopupHide()
}
}