更新记录

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 拍照成功 tempFilePathtempImagePathrawFilePathsizefileSizewidthheight
bindphoto 拍照成功的兼容事件 photo
error 相机初始化、拍照、写文件等失败 errMsg
devicechange 摄像头方向变化 devicePosition
flashchange 闪光灯模式变化 flash
zoomchange 缩放变化 zoom

业务页面通常只监听 @photo 即可,不建议同时给 @photo@bindphoto 绑定同一个回调,避免同一次拍照处理两遍。

Methods

方法 参数 说明
takePhoto() 触发拍照,成功后派发 photo 事件。
switchCamera() 插件内部切换前后摄。示例页采用修改 devicePosition 的方式切换,不直接调用该方法。
setFlashMode(mode) mode: string 设置闪光灯模式,支持 offonautotorch
setZoomValue(value) value: number 设置缩放倍率。

完整页面流程

  1. 页面加载时请求相机权限:onLoad -> requestCameraPermission()
  2. 渲染 yt-camera,传入 devicePositionflashzoomoutputWidthoutputHeightjpegQuality
  3. ready 事件返回 maxZoom,用于设置滑块最大值。
  4. 点击拍照按钮时通过 this.$refs.cam.takePhoto() 调用原生拍照。
  5. photo 事件返回临时图片路径,页面赋值给 photoPath 后使用 <image> 展示。
  6. 切换摄像头时修改 devicePosition,插件监听属性变化后切换原生摄像头。
  7. 修改闪光灯或缩放时,同步更新页面状态并调用插件实例方法。

示例入口

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"> 使用。
  • 如果业务层要做拍照遮罩,建议像示例页一样用绝对定位覆盖在相机组件上方,不要销毁相机组件本身。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

<uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" android:required="false" /> <uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

暂无用户评论。