更新记录
0.1.7(2026-05-27)
修复已知问题
0.1.6(2026-05-27)
更新使用文档
0.1.5(2026-05-27)
新增ios端功能
查看更多平台兼容性
uni-app(4.45)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| √ | √ | × | × | √ | √ | 5.0 | 12 | × |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| - | - | - | - | - | - | - | - | - | - | - | - |
uni-app x(5.0)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| - | - | - | - | - | - |
yt-camera 自定义相机插件使用文档
yt-camera 是用于 App 端 nvue 页面的 UTS 原生相机组件。本文档基于项目示例页 pages/custom-camera/custom-camera.nvue 整理,适用于需要自定义拍照按钮、切换前后摄、闪光灯、缩放和展示拍照结果的场景。
适用范围
| 平台 | 支持情况 | 说明 |
|---|---|---|
| App Android | 支持 | 使用 Android 原生相机能力。 |
| App iOS | 支持 | 使用 iOS 原生相机能力,需 iOS 自定义基座或云打包环境。 |
| H5 / 小程序 | 不支持 | 本插件为 App 原生相机组件。 |
注意:iOS 真机在 Windows 上使用标准基座无法运行 UTS 插件。如需验证 iOS 原生能力,请使用自定义基座、云打包或 macOS/Xcode 相关环境。
基础用法
在 nvue 页面中直接使用 yt-camera 组件,并给组件设置明确宽高。
<template>
<view class="page">
<yt-camera
ref="cam"
class="camera"
:devicePosition="devicePosition"
:flash="flash"
:zoom="zoom"
:outputWidth="750"
:outputHeight="1000"
:jpegQuality="90"
:mirrorFrontCamera="true"
@ready="onReady"
@photo="onPhoto"
@error="onError"
@devicechange="onDeviceChange"
@flashchange="onFlashChange"
@zoomchange="onZoomChange"
/>
<view v-if="photoPath" class="preview-mask">
<image class="preview-image" :src="photoPath"></image>
</view>
</view>
</template>
.page {
flex: 1;
background-color: #0f0f10;
}
.camera {
width: 750rpx;
height: 1000rpx;
}
.preview-mask {
position: absolute;
top: 0;
left: 0;
z-index: 999;
width: 750rpx;
height: 1100rpx;
}
.preview-image {
width: 750rpx;
height: 1000rpx;
}
页面数据
示例页使用以下状态控制相机。
export default {
data() {
return {
devicePosition: "back",
flash: "off",
zoom: 1,
maxZoom: 5,
maxPicturePixels: 8000000,
photoPath: "",
cameraPermissionGranted: false,
};
},
};
Android 权限处理
示例页在 onLoad 中调用 requestCameraPermission()。iOS 不走 plus.android.requestPermissions,会直接标记为已授权;iOS 权限文案由 Info.plist 配置。
onLoad() {
this.requestCameraPermission();
},
methods: {
requestCameraPermission() {
// #ifdef APP-PLUS
if (typeof plus === "undefined" || !plus.android || !plus.android.requestPermissions) {
this.cameraPermissionGranted = true;
return;
}
plus.android.requestPermissions([
"android.permission.CAMERA"
], (result) => {
const granted = Array.isArray(result.granted) && result.granted.indexOf("android.permission.CAMERA") !== -1;
this.cameraPermissionGranted = granted;
if (!granted) {
uni.showToast({ icon: "none", title: "请先开启相机权限" });
}
}, () => {
this.cameraPermissionGranted = false;
uni.showToast({ icon: "none", title: "请求相机权限失败" });
});
return;
// #endif
this.cameraPermissionGranted = true;
},
}
事件数据读取
UTS 事件在不同端可能表现为 Map、普通对象,或包在 e.detail 中。建议统一封装读取方法。
methods: {
getEventValue(e, key) {
try {
if (e && e.detail) {
if (e.detail.get) return e.detail.get(key);
if (e.detail[key] !== undefined) return e.detail[key];
}
if (e && e.get) return e.get(key);
if (e && e[key] !== undefined) return e[key];
} catch (err) {}
return undefined;
},
}
常用事件
methods: {
onReady(e) {
try {
this.maxZoom = (e && (e.get ? e.get("maxZoom") : e.maxZoom)) || 5;
} catch (err) {
this.maxZoom = 5;
}
},
onPhoto(e) {
try {
const path = this.getEventValue(e, "tempFilePath") || this.getEventValue(e, "tempImagePath") || "";
this.photoPath = path || "";
if (this.photoPath) {
uni.showToast({ icon: "none", title: "路径: " + this.photoPath });
}
} catch (err) {
this.photoPath = "";
}
},
onError(e) {
let msg = "相机错误";
try {
msg = e && e.get ? (e.get("errMsg") || msg) : ((e && e.errMsg) || msg);
} catch (err) {}
uni.showToast({ icon: "none", title: msg });
},
onDeviceChange(e) {
try {
this.devicePosition = e && e.get ? e.get("devicePosition") : this.devicePosition;
} catch (err) {}
},
onFlashChange(e) {
try {
this.flash = e && e.get ? e.get("flash") : this.flash;
} catch (err) {}
},
onZoomChange(e) {
try {
this.zoom = e && e.get ? e.get("zoom") : this.zoom;
} catch (err) {}
},
}
通过 ref 调用相机方法
methods: {
getCam() {
return this.$refs.cam;
},
takePhoto() {
const cam = this.getCam();
if (cam && cam.takePhoto) cam.takePhoto();
},
switchCamera() {
this.devicePosition = this.devicePosition === "back" ? "front" : "back";
},
cycleFlash() {
const next = this.flash === "off" ? "on" : this.flash === "on" ? "auto" : this.flash === "auto" ? "torch" : "off";
this.flash = next;
const cam = this.getCam();
if (cam && cam.setFlashMode) cam.setFlashMode(next);
},
onZoomSlider(e) {
const v = (e && e.detail && e.detail.value) || 1;
this.zoom = v;
const cam = this.getCam();
if (cam && cam.setZoomValue) cam.setZoomValue(v);
},
}
Props
| 属性 | 类型 | 默认值 | 示例值 | 说明 |
|---|---|---|---|---|
devicePosition |
String |
"back" |
"back" / "front" |
摄像头方向,后置或前置。 |
flash |
String |
"off" |
"off" / "on" / "auto" / "torch" |
闪光灯模式。 |
zoom |
Number |
1 |
1 |
缩放倍率,建议范围为 1 ~ maxZoom。 |
outputWidth |
Number |
0 |
750 |
输出图片目标宽度,具体裁剪/压缩行为以原生实现为准。 |
outputHeight |
Number |
0 |
1000 |
输出图片目标高度,示例页用于竖版拍照。 |
jpegQuality |
Number |
90 |
90 |
JPEG 质量,通常为 1 ~ 100。 |
mirrorFrontCamera |
Boolean |
true |
true |
前置摄像头是否镜像。 |
showControls |
Boolean |
false |
false |
是否显示插件内部控制按钮;自定义 UI 时保持 false。 |
Events
| 事件名 | 触发时机 | 常用字段 |
|---|---|---|
ready |
相机预览初始化完成 | maxZoom |
photo |
拍照成功 | tempFilePath、tempImagePath、rawFilePath、size、fileSize、width、height |
bindphoto |
拍照成功的兼容事件 | 同 photo |
error |
相机初始化、拍照、写文件等失败 | errMsg |
devicechange |
摄像头方向变化 | devicePosition |
flashchange |
闪光灯模式变化 | flash |
zoomchange |
缩放变化 | zoom |
业务页面通常只监听 @photo 即可,不建议同时给 @photo 和 @bindphoto 绑定同一个回调,避免同一次拍照处理两遍。
Methods
| 方法 | 参数 | 说明 |
|---|---|---|
takePhoto() |
无 | 触发拍照,成功后派发 photo 事件。 |
switchCamera() |
无 | 插件内部切换前后摄。示例页采用修改 devicePosition 的方式切换,不直接调用该方法。 |
setFlashMode(mode) |
mode: string |
设置闪光灯模式,支持 off、on、auto、torch。 |
setZoomValue(value) |
value: number |
设置缩放倍率。 |
完整页面流程
- 页面加载时请求相机权限:
onLoad -> requestCameraPermission()。 - 渲染
yt-camera,传入devicePosition、flash、zoom、outputWidth、outputHeight、jpegQuality。 ready事件返回maxZoom,用于设置滑块最大值。- 点击拍照按钮时通过
this.$refs.cam.takePhoto()调用原生拍照。 photo事件返回临时图片路径,页面赋值给photoPath后使用<image>展示。- 切换摄像头时修改
devicePosition,插件监听属性变化后切换原生摄像头。 - 修改闪光灯或缩放时,同步更新页面状态并调用插件实例方法。
示例入口
uni.navigateTo({
url: "/pages/custom-camera/custom-camera"
});
实际路径以项目 pages.json 配置为准。
注意事项
- 组件必须放在 nvue 页面中,并设置明确宽高,否则预览层可能无法正确布局。
- iOS 端需要在
uni_modules/yt-camera/utssdk/app-ios/Info.plist中配置相机权限描述。 - Android 端需要声明
android.permission.CAMERA,当前插件目录已包含对应AndroidManifest.xml。 photo事件返回的路径一般是file://临时文件路径,可直接作为<image :src="photoPath">使用。- 如果业务层要做拍照遮罩,建议像示例页一样用绝对定位覆盖在相机组件上方,不要销毁相机组件本身。

收藏人数:
购买普通授权版(
试用
赞赏(0)
下载 4
赞赏 0
下载 12142256
赞赏 1918
赞赏
京公网安备:11010802035340号