更新记录
1.0.0(2026-02-24)
自定义相机
平台兼容性
uni-app(4.57)
| Vue2 | Vue2插件版本 | Vue3 | Vue3插件版本 | Chrome | Safari | app-vue | app-nvue | app-nvue插件版本 | Android | Android插件版本 | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | 1.0.0 | √ | 1.0.0 | × | × | × | √ | 1.0.0 | 10.0 | 1.0.0 | × | × |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | × | × | × | - | × | × |
uni-app x(4.57)
| Chrome | Safari | Android | Android插件版本 | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|---|
| × | × | 10.0 | 1.0.0 | × | × | × |
插件地址https://ext.dcloud.net.cn/plugin?id=26956
使用说明
导入示例项目制作自定义基座 运行到安卓手机或者模拟器
购买源码版直接修改kotlin代码,很大提高了扩展性。 写本插件的初衷是现有的相机插件没有一个能完全满足我的需要,尝试了很多插件要么不能调分辨率,要么不缩放等,所以结合ai和自学uts插件和kotlin写了一个,可能不是很完善。 第一次尝试安卓uts原生插件,可能存在一些问题,请及时反馈 如需更多功能购买源码版自行修改,比如清晰度分辨率保存的地址很简单改个参数就行了。
目前主要实现功能
- 拍照
- 录像
- 切换摄像头
- 缩放
- 预览
插件没有获取权限需要在你项目获取相机相册麦克风权限参考示例项目 安卓模块配置需要勾上相机和录音 使用示例
<template>
<view class="ima-camera" style="" :style="{ width: screen.windowWidth+1, height: screen.windowHeight+1 }">
<my-camera class="CameraPreview" ref="cameraView"
@returNevent="returNevent"
@errorEvent="errorEvent"
:style="`height: ${screen.windowWidth*1.777}px;width:${screen.windowWidth}px`"></my-camera>
<cover-view class="camera-timer">
<text class="timer">{{ videTimer }}</text>
</cover-view>
<view v-if="!videoIng" @tap="flip" class=" flip" >
<text style="color: #ffffff;">切换摄像头</text>
</view>
<view class="camera-menu" style="width: 200px;">
<view class=" " >
<slider block-size="28" @changing="slider" :value="sliderval" :max="1" :min="0" :step="0.01"></slider>
</view>
<view class=" ">
<button @tap="photograph" style="color:#ffffff;backgroundColor:#32b16c;borderColor:#32b16c">拍照</button>
<button v-if="videoIng" @tap="endVideo" style="color:#ffffff;backgroundColor:#32b16c;borderColor:#32b16c">结束录制</button>
<button v-else @tap="startVideo" style="color:#ffffff;backgroundColor:#e5004f;borderColor:#e5004f">开始录制</button>
</view>
</view>
</view>
</template>
<script setup>
import {onLoad,onReady,onUnload, } from "@dcloudio/uni-app";
import {ref,getCurrentInstance} from 'vue'
const { windowWidth, windowHeight } = uni.getSystemInfoSync();
const screen=ref({
windowWidth:windowWidth,
windowHeight:windowHeight
})
console.log('宽高',windowWidth,windowHeight)
const cameraView=ref(null)
const videoIng=ref(false)
const sliderval=ref(0)
const videTimer=ref('00:00')
let back=true
let timer=null
onLoad((opt)=>{
})
onReady(()=>{
})
onUnload(()=>{
})
((res)=>{
const { windowWidth, windowHeight } = uni.getSystemInfoSync();
screen.value.windowWidth=windowWidth
screen.value.windowHeight=windowHeight
// console.log('aaaa',res)
})
const photograph=()=>{//拍照
cameraView.value.takePhoto()
}
const returNevent=(res)=>{//所有数据返回通过事件返回
console.log('回调事件',res.detail)
if(res?.detail?.name==='initialize'){//初始化成功
cameraView.value.getZoomState();
}else if(res?.detail?.name==='zoomState'){//缩放当前值 0-10
let data=res?.detail?.data||0
sliderval.value=Number(data.toFixed(1))
}else if(res?.detail?.name==='switchCamera'){//切换摄像头回调
setTimeout(()=>{
cameraView.value.getZoomState();
},500)
}else if(res?.detail?.name==='startVideo'){//开始录制回调
let seconds = 0
videoIng.value = true
timer = setInterval(() => {
seconds++
const mm = String(Math.floor(seconds / 60)).padStart(2, '0')
const ss = String(seconds % 60).padStart(2, '0')
videTimer.value = `${mm}:${ss}`
}, 1000)
}else if(res?.detail?.name==='endVideo'){//结束录制回调
clearInterval(timer)
videTimer.value = '00:00'
videoIng.value = false
uni.showModal({
title: '录像成功',
content: '视频地址:'+res?.detail?.data,
success: function(res) {
if (res.confirm) {
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
}else if(res?.detail?.name==='pahto'){
uni.showModal({
title: '拍照成功',
content: '照片地址:'+res?.detail?.data,
success: function(res) {
if (res.confirm) {
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
}
}
const errorEvent=(res)=>{//错误回调事件
const data=res.detail
console.log('错误回调事件',data)
uni.showModal({
title: '提示',
content: data.error||'错误!',
showCancel:false,
success: function (res) {
if (res.confirm) {
} else if (res.cancel) {
}
}
});
}
const flip=()=>{//切换摄像头
cameraView.value.switchCamera()
}
const startVideo=()=>{//开始录制
cameraView.value.startRecording()
}
const endVideo=()=>{//结束录制
uni.showModal({
title: '提示',
content: '确认停止录制!',
success: function(res) {
if (res.confirm) {
cameraView.value.stopRecording()
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
}
const slider=(val)=>{//滑动变焦
if(sliderval.value===val.detail.value){
return
}
sliderval.value=val.detail.value
cameraView.value.setZoom(sliderval.value);
}
const requestAndroidPermission=(permissionID)=>{
return new Promise((resolve, reject) => {
plus.android.requestPermissions(
[permissionID],
function(resultObj) {
var result = 0;
for (var i = 0; i < resultObj.granted.length; i++) {
var grantedPermission = resultObj.granted[i];
console.log('已获取的权限:' + grantedPermission);
result = 1
}
for (var i = 0; i < resultObj.deniedPresent.length; i++) {
var deniedPresentPermission = resultObj.deniedPresent[i];
console.log('拒绝本次申请的权限:' + deniedPresentPermission);
result = 0
}
for (var i = 0; i < resultObj.deniedAlways.length; i++) {
var deniedAlwaysPermission = resultObj.deniedAlways[i];
console.log('永久拒绝申请的权限:' + deniedAlwaysPermission);
result = -1
}
resolve(result);
// 若所需权限被拒绝,则打开APP设置界面,可以在APP设置界面打开相应权限
// if (result != 1) {
// gotoAppPermissionSetting()
// }
},
function(error) {
console.log('申请权限错误:' + error.code + " = " + error.message);
resolve({
code: error.code,
message: error.message
});
}
);
});
}
requestAndroidPermission('android.permission.WRITE_EXTERNAL_STORAGE')
requestAndroidPermission('android.permission.READ_EXTERNAL_STORAGE')
requestAndroidPermission('android.permission.CAMERA')
requestAndroidPermission('android.permission.RECORD_AUDIO')
</script>
<style lang="scss">
.ima-camera {
display: flex;
justify-content: center;
background: #000;
}
.CameraPreview{
}
.flip {
position: fixed;
top: 90rpx;
right: 50rpx;
}
.camera-menu {
position: fixed;
bottom: 30px;
z-index: 999;
}
.camera-timer {
position: fixed;
top: 100rpx;
left: 60rpx;
.timer {
text-align: center;
color: #fff;
font-size: 26rpx;
}
}
</style>

收藏人数:
购买源码授权版(
试用
使用 HBuilderX 导入示例项目
赞赏(0)
下载 2
赞赏 0
下载 11330532
赞赏 1864
赞赏
京公网安备:11010802035340号