更新记录
1.2(2026-09-30)
新增录像(暂停/继续、画质/限时/限大小)、水印预览与成片烧录(地理钉/多图标/斜向平铺)、连拍、人脸框与抓脸、微距、超广角、缩放/曝光/对焦 API、HDR·夜景成像增强与成片锐
1.1(2024-10-22)
支持设换摄像头 支持声音设置
1.0(2024-04-10)
- 支持任意自定义界面
- 支持手势缩放
- 支持裁剪(手势拖动、比例设置、旋转)
- 支持自定义保存路径
平台兼容性
| Android | Android CPU类型 | iOS |
|---|---|---|
| 适用版本区间:5.0 - 14.0 | armeabi-v7a:支持,arm64-v8a:支持,x86:支持 | × |
原生插件通用使用流程:
- 购买插件,选择该插件绑定的项目。
- 在HBuilderX里找到项目,在manifest的app原生插件配置中勾选模块,如需要填写参数则参考插件作者的文档添加。
- 根据插件作者的提供的文档开发代码,在代码中引用插件,调用插件功能。
- 打包自定义基座,选择插件,得到自定义基座,然后运行时选择自定义基座,进行log输出测试。
- 开发完毕后正式云打包
付费原生插件目前不支持离线打包。
Android 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/android
iOS 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/ios
注意事项:使用HBuilderX2.7.14以下版本,如果同一插件且同一appid下购买并绑定了多个包名,提交云打包界面提示包名绑定不一致时,需要在HBuilderX项目中manifest.json->“App原生插件配置”->”云端插件“列表中删除该插件重新选择
自定义相机插件(组件版)Ba-CameraView
简介
Ba-CameraView 是一款自定义相机原生组件,可在任意 nvue 界面嵌入使用。支持拍照、裁剪、水印、微距、录像、连拍、缩放/曝光、视频流、人脸抓拍等能力。
核心能力
- 任意自定义界面(组件模式) — 相机只占一块预览区,全屏/半屏/卡片均可;上下左右任意叠业务控件
- 取景控制 — 前后摄、闪光灯、手势/API 缩放、曝光、点击对焦、微距、超广角
- 拍照 — 自定义路径、JPEG 画质、前摄镜像、拍后裁剪、连拍
- 录像 — 开始 / 暂停 / 继续 / 停止;画质档位、限时、限大小、有声/无声
- 水印 —
Ba-WatermarkView预览 + 成片烧录(所见即所得);地理钉、多图标、斜向平铺 - 人脸 — 原生框检测;
captureFace抓整帧 + 人脸图(可多人脸) - 画质增强 — HDR/夜景等成像增强(机型支持时)、成片锐化
- 预览对齐 — ViewPort 预览与成片 FOV 一致;支持全屏 / 9:16 / 1:1 等比例布局
注意:原生组件请使用 nvue
兼容说明:保留旧版基础用法(load / takePicture / switchCamera / setListener),旧业务一般无需改代码;新增能力为可选扩展。
有建议和需要,请联系QQ:2579546054
也可关注博客,实时更新最新插件:
一、组件说明
| 组件名 | 说明 |
|---|---|
| Ba-CameraView | 相机预览与拍照 / 录像控制 |
| Ba-WatermarkView | 预览水印叠层(需叠在相机预览区域上方) |
功能一览
| 能力 | 状态 | 说明 |
|---|---|---|
| 拍照 | ✅ | takePicture |
| 连拍 | ✅ | takeBurst |
| 裁剪 | ✅ | isCrop + cropType + scaleFlag |
| 水印预览 | ✅ | Ba-WatermarkView |
| 水印烧录 | ✅ | setWaterMark / takePicture.waterMark / load.waterMark |
| 地理水印 | ✅ | items 图文 + location 等内置图标 |
| 多图标/任意坐标 | ✅ | items[]:type=icon/group + x/y/anchor |
| 全屏斜向水印 | ✅ | items[]:type=tile(姓名工号等) |
| 前后摄 | ✅ | switchCamera / load.facingFront |
| 拍照/录像会话 | ✅ | setSessionMode:photo / video(切换时重新绑定,清晰度更好) |
| 闪光灯 | ✅ | setFlashMode / cycleFlashMode(off/auto/on);openLight/closeLight 常亮 Torch |
| 手势缩放 | ✅ | load.zoom |
| 点击对焦 | ✅ | 预览点击;原生四角对焦框;listener focus |
| 预览宽高比 | ✅ | Demo:previewAspect + takePicture scaleFlag/scaleW/H |
| 缩放 API | ✅ | setZoom / getZoomRange |
| 曝光补偿 | ✅ | setExposureCompensation |
| JPEG 画质 | ✅ | load.jpegQuality(进页绑定生效)/ setJpegQuality(下次绑定生效) |
| 前摄镜像 | ✅ | load.mirrorFront / setMirrorFront |
| 成像增强 | ✅ | setCaptureEnhance:none / hdr / night / auto / bokeh / face(仅拍照会话;依赖 OEM) |
| 成片锐化 | ✅ | setSharpen:amount 0=关,默认约 0.35 |
| 目标分辨率 | ✅ | load.targetSize |
| 微距 | ✅ | enableMacro / disableMacro / toggleMacro |
| 人脸框 | ✅ | startFaceDetect / captureFace(ML Kit;原生叠层;可抓整帧+人脸) |
| 录像 | ✅ | startRecord / stopRecord |
| 录像暂停 | ✅ | pauseRecord / resumeRecord |
| 画质档位 | ✅ | setVideoQuality:SD / HD / FHD / UHD |
| 限时 / 限大小 | ✅ | maxDurationMs / maxFileSize |
| 超广角切换 | ✅ | setUltraWide(无独立超广角镜头时可能失败) |
| 录像水印 | ❌ | 暂不支持 |
| 自动微距 | ❌ | 暂不支持 |
二、快速开始
Demo 提供两种布局(API 相同,仅容器不同):
| 布局 | 路径 | 说明 |
|---|---|---|
| 全屏 | pages/camera/cameraQuick |
预览铺满屏幕,控件叠在预览上 |
| 半屏 | pages/camera/cameraQuickHalf |
固定高度容器嵌入页面,上下可放业务内容 |
1)全屏布局
<template>
<view class="container">
<Ba-CameraView ref="cameraView" class="camera-view" :load="loadData"></Ba-CameraView>
<!-- 水印预览(可选):叠在相机区域上 -->
<!-- <Ba-WatermarkView ref="watermarkView" class="watermark-view"></Ba-WatermarkView> -->
</view>
</template>
.container { flex: 1; height: 100%; }
.camera-view { flex: 1; width: 750rpx; }
2)半屏嵌入
<template>
<view class="page">
<!-- 上方业务内容 -->
<text class="tip">标题 / 表单等</text>
<view class="camera-box" :style="{ height: cameraH + 'px' }">
<Ba-CameraView ref="cameraView" class="camera-view" :load="loadData"></Ba-CameraView>
</view>
<!-- 下方快门、说明等 -->
</view>
</template>
.camera-box {
width: 702rpx;
/* height 由脚本设为约半屏,如 windowHeight * 0.42 */
border-radius: 20rpx;
overflow: hidden;
background-color: #000;
}
.camera-view { flex: 1; width: 702rpx; }
3)基础调用示例
export default {
data() {
return {
loadData: {
isToast: true,
isShowVibrate: true, // 拍照落盘 / 录像结束时震动
isShowBeep: true, // 拍照落盘 / 录像结束时提示音
zoom: true // 手势捏合缩放
}
}
},
onReady() {
this.$refs.cameraView.setListener((res) => {
if (res.action === 'error') {
console.log(res.msg)
}
})
},
methods: {
onTakePicture() {
this.$refs.cameraView.takePicture((res) => {
// res.ok / res.msg / res.data.path
console.log(JSON.stringify(res))
})
},
switchCamera() {
this.$refs.cameraView.switchCamera((res) => {
console.log(res.msg)
})
},
openLight() {
this.$refs.cameraView.openLight((res) => {})
},
closeLight() {
this.$refs.cameraView.closeLight((res) => {})
}
}
}
统一回调格式
| 字段 | 类型 | 说明 |
|---|---|---|
| ok | Boolean | 是否成功 |
| msg | String | 提示信息 |
| data | Object | 业务数据(如 path、enabled、durationMs 等) |
三、load 配置
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| isToast | Boolean | - | 成功时是否原生 Toast |
| isShowVibrate | Boolean | true | 拍摄完成震动(照片写入成功、或录像结束保存时;含随后还要进裁剪) |
| isShowBeep | Boolean | false | 拍摄完成提示音(时机同上) |
| zoom | Boolean | false | 是否支持手势捏合缩放 |
| macro | Boolean | false | 启动即进入微距 |
| facingFront | Boolean | false | 启动使用前置摄像头 |
| targetSize | Number | 0 | 目标短边分辨率;0 = 自适应(推荐/默认,不锁分辨率);如 720 / 1080 才会按短边偏好选档 |
| jpegQuality | Number | 100 | JPEG 压缩质量 1-100;进入页面首次绑定时生效 |
| mirrorFront | Boolean | false | 前置:预览与成片是否水平镜像(后置无效;默认关,利于文字/水印左右正确) |
| waterMark | Object | - | 初始水印配置(供拍照烧录,见水印章节) |
loadData: {
isToast: true,
isShowVibrate: true,
isShowBeep: true,
zoom: true,
facingFront: false,
targetSize: 0,
jpegQuality: 95,
mirrorFront: false
}
四、拍照 API
takePicture(callback, options)
| 属性名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| path | String | 否 | 图片保存路径;空则写入应用临时目录 |
| isCrop | Boolean | 否 | 是否裁剪,默认 false |
| cropType | Number | 否 | 0 UCrop · 1 android-image-cropper |
| scaleFlag | Number | 否 | 0 预览比例 · 1 9:16 · 2 3:4 · 3 1:1 · 4 4:3 |
| scaleW / scaleH | Number | 否 | 自定义裁剪比例(覆盖 scaleFlag);如 16:9 用 scaleW:16, scaleH:9 |
| jpegQuality | Number | 否 | 记录 JPEG 质量偏好(非本张立刻生效;下次绑定后生效,如切摄像头) |
| mirrorFront | Boolean | 否 | 本次前摄预览+成片是否镜像 |
| waterMark | Object | 否 | 本次成片水印(覆盖);不传则沿用 setWaterMark / load.waterMark |
预览宽高比:见下文「推荐:预览比例与成片对齐」。原生通过 CameraX
ViewPort让预览与成片 FOV 一致;scaleFlag:0(full)时成片即预览可见区域。指定其它比例(或scaleW/H)会在此基础上再裁;若预览框比例与传入不一致,可能出现「方预览、竖成片」等所见非所得。jpegQuality:CameraX 在绑定
ImageCapture时固定压缩质量。运行中setJpegQuality/takePicture({ jpegQuality })只写入偏好,当前这一张仍用绑定时的质量;下次绑定(如切摄像头、重新进页)才用新值。进页即生效请用load.jpegQuality。
回调 data
| 属性名 | 类型 | 说明 |
|---|---|---|
| path | String | 图片路径 |
takeBurst(callback, options) 连拍
| 属性 | 类型 | 默认 | 说明 |
|---|---|---|---|
| count | Number | 3 | 连拍张数 |
| intervalMs | Number | 400 | 间隔毫秒 |
| jpegQuality | Number | - | 同 takePicture:只记录,下次绑定生效 |
| waterMark | Object | - | 水印(每张都会烧录) |
| scaleFlag | Number | - | 同 takePicture,连拍每张按此比例裁切 |
| scaleW / scaleH | Number | - | 自定义比例(覆盖 scaleFlag) |
成功时 data.paths 为路径数组,data.count 为张数。
推荐:预览比例与成片对齐(必读)
原生用 CameraX ViewPort + UseCaseGroup,预览与拍照共享同一可视裁切。业务侧请理解两套概念:
| 概念 | 谁控制 | 作用 |
|---|---|---|
| 预览容器尺寸 | UniApp 布局(CSS / flex / 固定宽高) | 决定用户在屏幕上看到的取景框 |
**scaleFlag / scaleW/H** |
takePicture / takeBurst 参数 |
成片额外裁切;0 表示不再额外裁,跟 ViewPort |
推荐做法(多数业务)
默认使用 full(scaleFlag: 0),用布局把 Ba-CameraView(及水印)做成目标比例:
- 全屏铺满 → 容器
flex:1全屏 +scaleFlag: 0 - 半屏方块 / 卡片 → 容器做成正方形或你需要的比例 +
scaleFlag: 0 - 竖屏条(9:16)→ 容器做成 9:16 +
scaleFlag: 0
这样 成片 FOV = 预览框所见,水印坐标也同一框,所见即所得。
// 推荐:布局已是目标比例时
this.$refs.cameraView.takePicture(cb, { scaleFlag: 0 })
// 或不传 scaleFlag(内部默认按预览区域)
何时传固定比例(9:16 / 1:1 等)
仅当 预览框也会做成同一比例,并明确要强制成片为该比时,再传 scaleFlag: 1~4 或 scaleW/H。Demo 的 previewAspect 会同时改容器尺寸并传入对应参数。
设置 full 时,容器不同会怎样
full 不会强行铺满整屏;只表示「成片跟当前 PreviewView 实际大小对齐」。
| 设置 | 容器实际形状 | 预览 | 成片 |
|---|---|---|---|
full |
全屏竖屏手机 | 铺满屏幕 | ≈ 屏幕所见 |
full |
正方形 | 方框内取景(FILL_CENTER) | ≈ 方框所见 |
full |
9:16 竖条 | 竖条内取景 | ≈ 竖条所见 |
结论:布局做成啥比例,在 full 下预览和成片就一起变成啥比例。
错配会怎样(避免)
| 设置 / 传参 | 容器 | 结果 |
|---|---|---|
scaleFlag: 1(9:16) |
却是正方形 | 预览方、成片竖(中心再裁),所见 ≠ 所得;水印相对位置也可能偏 |
previewAspect: '9:16'(Demo)但 CSS 仍把相机撑成方 |
同上 | 同上 |
| 固定比例且框与参数一致 | 一致 | 预览 ≈ 成片 |
一句话:要所见即所得 → 优先 full,比例交给容器;只有成片必须强制某比且预览框也按该比做时,再设固定 scaleFlag。
水印叠层
Ba-WatermarkView 必须与相机放在同一容器内叠放(position: absolute 盖住预览),不要盖住整页(含顶部按钮区),否则「左上」会画到按钮上。
.camera-wrap { flex: 1; position: relative; overflow: hidden; }
.camera-view { flex: 1; }
.watermark-view { position: absolute; top: 0; left: 0; right: 0; bottom: 0; }
Demo:previewAspect(预览宽高比)
Demo 按场景隔离存储:ba_camera_demo_settings__{scene},字段 previewAspect。
| 值 | 预览框(Demo 计算) | 拍照传入 |
|---|---|---|
full |
铺满可用区域 | scaleFlag: 0(跟预览 View) |
9:16 |
9:16 | scaleFlag: 1 |
3:4 |
3:4 | scaleFlag: 2 |
1:1 |
1:1 | scaleFlag: 3 |
4:3 |
4:3 | scaleFlag: 4 |
16:9 |
16:9 | scaleW: 16, scaleH: 9 |
各场景默认(恢复默认后生效;本地已存配置需点「恢复默认」):
| 场景 | previewAspect | 其它 |
|---|---|---|
| 快速开始 / 综合 / 微距 / 录像 / 流 | full |
— |
| 拍照 / 裁剪 | full |
成片 scaleFlag 默认 3(1:1) |
| 水印 / 水印相机 | **9:16** |
竖屏预览,贴近手机拍摄 |
- 设置页:场景专属项在上方;前摄 / JPEG / 缩放等在底部 「更多参数」→ 展开
- 综合效果 / 水印 / 水印相机:顶栏也可切换预览比例
- 业务侧若不走 Demo:自行约束预览容器宽高;推荐
scaleFlag: 0,或传与容器一致的scaleFlag/scaleW/H
const PREVIEW_ASPECTS = {
'full': { scaleFlag: 0 },
'9:16': { scaleFlag: 1 },
'3:4': { scaleFlag: 2 },
'1:1': { scaleFlag: 3 },
'4:3': { scaleFlag: 4 },
'16:9': { scaleFlag: 0, scaleW: 16, scaleH: 9 }
}
// 仅当预览框已是 9:16 时再这样传
this.$refs.cameraView.takePicture(cb, Object.assign({
jpegQuality: 95
}, PREVIEW_ASPECTS['9:16']))
switchCamera / setSessionMode / setFlashMode / cycleFlashMode / openLight / closeLight
切换前后摄像头(录像中不可切换)。
拍照 / 录像会话(推荐,类似系统相机):setSessionMode(cb, { mode: 'photo'|'video' })。
photo:只绑预览+拍照,偏好高像素成片video:绑预览+拍照+录像,保证能录
切换会短暂重载预览。默认进入为photo;系统相机 Demo 在切「拍照/录像」Tab 时会调用。纯录像页可在就绪后调一次video,或依赖startRecord内自动ensureVideoBound。
成功时data.sessionMode/videoAvailable。
拍照闪光:setFlashMode(cb, { mode: 'auto'|'off'|'on'|'torch' }),默认建议 auto;cycleFlashMode 按 自动→开启→常亮→关闭 循环。
成功时 data.flashMode。常亮 torch 会打开 Torch;其余模式关闭 Torch。
openLight / closeLight / toggleLight 仍可用于单独控制常亮。
getCameraState 含 hasFlash / flashMode / torchOn / sessionMode。
缩放 / 曝光 / 状态
| 方法 | 说明 |
|---|---|
| setZoom(cb, { zoom }) | 设置缩放倍数(支持 <1 的超广角档,如 0.6) |
| getZoomRange(cb) | 返回 zoom / min / max |
| setUltraWide(cb, { enable }) | 切换后置超广角镜头;无独立超广角时可能失败;成功含 ultraWide / zoom / minZoom / maxZoom |
| setExposureCompensation(cb, { index }) | 设置曝光补偿 |
| getExposureCompensation(cb) | 返回 index / min / max |
| setJpegQuality(cb, { quality }) | 记录 JPEG 质量偏好(下次绑定后生效;不会立刻 rebind,避免拍照报未绑定) |
| setMirrorFront(cb, { mirror }) | 前摄预览与成片镜像;立即更新预览 |
| setCaptureEnhance(cb, { mode }) | 成像增强:none/hdr/night/auto/bokeh/face;仅拍照会话立即重绑;机型不支持自动回退 |
| getCaptureEnhance(cb) | 返回 requested / applied / available[] / fallback / reason / extensionsReady |
| setSharpen(cb, { amount }) | 成片锐化强度;0=关,建议 0.3~0.5;立即对后续拍照生效 |
| getSharpen(cb) | 返回 amount |
| setWaterMark(cb, cfg) | 写入成片烧录水印;之后拍照可不传 waterMark |
| clearWaterMark(cb) | 清除成片烧录水印 |
| getCameraState(cb) | 汇总 facingFront / hasFlash / torchOn / zoom / jpegQuality / captureEnhance / sharpenAmount 等 |
成像增强:基于 CameraX Extensions,效果取决于厂商实现,不等同系统相机 HDR+。录像会话会忽略增强(切回
photo后生效)。
用getCaptureEnhance看:available=本机支持列表;applied=当前是否真正绑上;fallback=true表示请求了但未生效(原因见reason)。
成片锐化:软件后处理,不依赖 OEM;默认约 0.35,可按观感调低或关闭。
五、微距 API
| 方法 | 说明 |
|---|---|
| enableMacro(cb, { zoomRatio }) | 开启微距,默认 zoomRatio=2.0 |
| disableMacro(cb) | 关闭微距 |
| toggleMacro(cb, { zoomRatio }) | 切换微距;成功时 data.enabled |
五.1、人脸框 API
基于 CameraX ImageAnalysis + ML Kit Face Detection。开启后原生在预览上绘制四角框;坐标也会通过 setListener 回调。
| 方法 | 说明 |
|---|---|
| startFaceDetect(cb, options?) | 启用人脸检测;录像中不可用;建议先 setSessionMode({ mode:'photo' }) |
| setFaceDetectOptions(cb, options) | 运行中改参;改分析分辨率会重绑 |
| getFaceDetectOptions(cb) | 查询当前参数 |
| stopFaceDetect(cb) | 关闭并清除框 |
| isFaceDetecting(cb) | 查询是否开启;含当前参数与 count |
| captureFace(cb, options?) | 从分析流裁切人脸图(非 ImageCapture 全幅拍照) |
startFaceDetect / setFaceDetectOptions
| 属性 | 类型 | 默认 | 说明 |
|---|---|---|---|
| boxColor / color | String | #FFFFFFFF |
框颜色,#RRGGBB 或 #AARRGGBB |
| intervalMs | Number | 200 | 检测间隔,建议 100~500 |
| analysisWidth | Number | 480 | 分析流目标宽 |
| analysisHeight | Number | 360 | 分析流目标高 |
| cropPad | Number | 0.18 | 裁脸相对检测框外扩比例,0~0.5 |
captureFace options
| 属性 | 类型 | 默认 | 说明 |
|---|---|---|---|
| all | Boolean | false | true:同一分析帧上检测到的人脸全部落盘 |
| index | Number | -1 | all 为 false 时有效:<0 取最大脸,否则按下标 |
| path | String | - | 单张时的保存路径;all:true 时可作目录提示(实际写入应用私有目录) |
| waitMs | Number | 3500 | 等待「带人脸的可裁切分析帧」超时毫秒(中途失败会继续等下一帧,超时再失败) |
captureFace 回调 data
| 属性 | 类型 | 说明 |
|---|---|---|
| framePath | String | 与人脸同一分析帧的整帧图(可能为空) |
| paths | String[] | 人脸图路径列表 |
| path | String | 首张人脸路径(兼容旧用法) |
| count | Number | 本次保存的人脸张数 |
listener face 的 data.faces[]
| 字段 | 说明 |
|---|---|
| left / top / right / bottom | 相对预览宽高的 0~1 归一化坐标 |
| leftPx / topPx / rightPx / bottomPx | 预览 View 像素坐标 |
// 推荐:拍照会话下做人脸(勿与录像会话强行四开)
this.$refs.cameraView.setSessionMode(() => {}, { mode: 'photo' })
this.$refs.cameraView.startFaceDetect((res) => {
console.log(res.ok, res.data)
}, {
boxColor: '#FFFFFFFF',
intervalMs: 200,
analysisWidth: 480,
analysisHeight: 360,
cropPad: 0.18
})
this.$refs.cameraView.setFaceDetectOptions((res) => {}, { intervalMs: 250, boxColor: '#FF4ADE80' })
this.$refs.cameraView.setListener((res) => {
if (res.action === 'face') {
// res.data.count / res.data.faces[]
}
})
this.$refs.cameraView.captureFace((res) => {
// res.data.framePath 整帧;res.data.paths 人脸;res.data.count
}, { all: true, waitMs: 3500 })
this.$refs.cameraView.stopFaceDetect(() => {})
注意:
- 依赖 ML Kit Face Detection,会增加 APK 体积;需可访问 Google ML Kit 模型(部分无 GMS 环境需自行验证)
- 建议在
**sessionMode: photo** 下使用;与录像四用例(预览+拍照+录像+分析)并存时,部分机型会绑失败并降级 - Demo「人脸框」页:设置可改框色 / 间隔 / 分析分辨率 / 裁切外扩;自动抓节奏(稳定时长、抓取间隔)为 Demo 逻辑,非原生必选参数
captureFace默认在waitMs(3500)内持续等待有人脸的分析帧再裁切;超时才返回失败(预览有框但瞬间无分析帧时,多数情况可等出来)all:true时同一分析帧裁多张,避免多次调用抓到不同时刻- 提高
analysisWidth/Height可能更准但更卡;改分辨率需重绑 - 抓取结果来自分析流分辨率,清晰度通常低于
takePicture成片
六、录像 API
| 方法 | 说明 |
|---|---|
| startRecord(cb, options) | 开始录像 |
| stopRecord(cb) | 停止录像;成功时 data.path;自动停止时含 reason / autoStopped |
| pauseRecord(cb) | 暂停录像 |
| resumeRecord(cb) | 继续录像 |
| isRecording(cb) / getRecordState(cb) | 查询状态 |
| setVideoQuality(cb, { quality }) | 设置画质 SD/HD/FHD/UHD(录像中不可改) |
startRecord options
| 属性 | 类型 | 默认 | 说明 |
|---|---|---|---|
| path | String | - | 视频保存路径 |
| withAudio | Boolean | true | 是否录音 |
| maxDurationMs | Number | 0 | 最长时长(毫秒),0 不限制;也可用 maxDuration(秒) |
| maxFileSize | Number | 0 | 最大文件字节,0 不限制 |
| quality | String | HD | SD / HD / FHD / UHD / LOWEST / HIGHEST |
注意:录像过程中无法切换摄像头 / 切换画质。
七、事件监听 setListener
| action | 说明 |
|---|---|
| error | 通用错误 |
| focus | 点击对焦(data.x / data.y 为预览内坐标;对焦框由原生绘制,勿再用 nvue fixed 叠白框) |
| face | 人脸检测(data.count / data.faces[];框由原生绘制) |
| recordStart | 开始录像 |
| recordStatus | 录像中状态(data.durationMs / data.bytes / data.paused) |
| recordPause / recordResume | 暂停 / 继续 |
| recordStop | 停止并保存 |
| recordLimit | 达到时长或大小上限自动停止 |
| recordError | 录像失败 |
| recordWarning | 如未授予麦克风权限,降级无声录像 |
八、水印(Ba-WatermarkView + 拍照烧录)
预览与成片共用同一套样式字段;推荐 一份 cfg 同步两边:
Ba-WatermarkView.updateConfig(cfg)→ 屏幕预览叠层Ba-CameraView.setWaterMark(cfg)→ 成片烧录缓存takePicture/takeBurst可不传waterMark(沿用第 2 步);仍传则会覆盖本次。
load.waterMark仅初始化成片侧,不会自动更新Ba-WatermarkView预览。
推荐用 items[] 描述多元素(多图标、图文组合、全屏斜向平铺、任意坐标)。
旧字段 texts / lines / position / icon 仍兼容,等价于单个图文块。
waterMark 顶层配置
| 属性 | 类型 | 默认 | 说明 |
|---|---|---|---|
| items | Array | - | 推荐:多元素列表,见下表 |
| texts / lines | - | - | 旧版单块文案(无 items 时生效) |
| visible | Boolean | true | 是否显示 / 是否烧录 |
| textColor / backgroundColor / textSize | - | - | 全局默认,可被 item 覆盖。颜色支持透明度 #AARRGGBB(AA=00 全透~FF 不透),亦支持 #RGB / #RRGGBB。textSize 为设计宽 360 单位:实际像素 ≈ 值 × 画布宽/360(如 15 → 1080 宽约 45px),随照片分辨率缩放,勿当绝对 px |
| lineGap | Number | 0.35 | 多行行间距,相对字体大小比例;>2 时按设计宽 360 单位兼容 |
| icon / iconPath / iconSize | - | none | 旧版单块图标;iconPath 优先,支持本地 / file:// / http(s);iconSize 同 textSize 单位 |
| showAccentLine | Boolean | true | 强调竖线:有图标时自动隐藏;未设 x/y 时仅左下/左上/居中绘制(右下/右上不画) |
| accentLineColor | String | #EFC46B | 强调竖线颜色(支持 #AARRGGBB) |
| accentLineWidth | Number | 0.25 | 竖线宽度,相对字体大小 |
| accentLineGap | Number | 0.5 | 竖线与背景块间距,相对字体大小 |
| bold | Boolean | false | 全局加粗 |
| padding | Number | 0.45 | 背景内边距,相对字体大小 |
| cornerRadius | Number | 0.25 | 背景圆角,相对字体大小 |
| margin | Number | 1.6 | 贴边边距:左上/左下等相对画布边缘(相对字体大小);自定义 x/y 时不生效 |
| position | Number | 0 | 旧版单块四角:0左下 · 1右下 · 2左上 · 3右上 · 4居中 |
items[] 元素
| 属性 | 说明 |
|---|---|
| type | icon 纯图标 · text/group 文本或图文组合 · tile 全屏斜向重复 |
| icon | 内置:location / user / star / check / none;也可直接传本地图片路径(见 iconPath) |
| iconPath | 自定义图标:支持本地绝对路径、file://、http(s);UniApp 的 /static/xxx.png 请先转成绝对路径 |
| iconSize | 图标大小(同 textSize:设计宽 360 单位),0 自适应 |
| text / texts / lines | 文案(tile / group / text);lines 内可设 bold |
| bold | 是否加粗(可被 line.bold 覆盖) |
| lineGap | 多行行间距,相对字体大小比例(默认 0.35=字高 35%);>2 时仍按旧「设计宽 360 单位」兼容 |
| padding / cornerRadius / margin | padding=背景内边距;cornerRadius=圆角;margin=贴边边距(四角定位时相对画布边缘) |
| showAccentLine / accentLineColor / accentLineWidth / accentLineGap | 强调竖线(规则同顶层) |
| x, y | 相对坐标 0~1(左上为原点);不填则用顶层 position 或默认左下 |
| anchor | 锚点:leftBottom(默认)/ leftTop / rightBottom / rightTop / center |
| position | 未设 x/y 时可用 0~4 四角 |
| angle / gapX / gapY | 仅 tile:旋转角(度;原生未传默认 -30,Demo 常用 -32)、水平/垂直间距(设计宽 360) |
| textColor / backgroundColor / textSize | 单元素样式覆盖;颜色支持 #AARRGGBB |
Demo「自定义」可开启 叠加斜向平铺(type=tile),参数与「全屏斜向工牌」共用,并在设置页标出字段名:text / textSize / textColor / bold / angle / gapX / gapY。
// 斜向平铺
items: [{
type: 'tile',
text: '张三 · 工号 10086',
textSize: 13,
textColor: '#55FFFFFF', // 支持透明度
bold: false,
angle: -32, // 旋转角(度)
gapX: 200, // 水平间距(设计宽360)
gapY: 110 // 垂直间距(设计宽360)
}]
// 自定义图文 + 底层斜向平铺(items 里同时放 tile 与 group)
items: [
{ type: 'tile', text: '…', angle: -32, gapX: 200, gapY: 110, textSize: 13, textColor: '#55FFFFFF' },
{ type: 'group', text: '地点', position: 0, /* … */ }
]
示例 1:时间地点 + 多图标任意位
const waterMark = {
visible: true,
items: [
{
type: 'group',
icon: 'location',
backgroundColor: '#00000000',
x: 0.04, y: 0.93, anchor: 'leftBottom',
lines: [
{ text: '河北省衡水市……初级中学', textSize: 14, textColor: '#ffffff' },
{ text: '2026-09-25 16:20 星期五', textSize: 12, textColor: '#CCFFFFFF' }
]
},
{ type: 'icon', icon: 'check', iconSize: 18, x: 0.94, y: 0.93, anchor: 'rightBottom' }
]
}
this.$refs.watermarkView.updateConfig(waterMark)
this.$refs.cameraView.setWaterMark(() => {}, waterMark)
this.$refs.cameraView.takePicture(cb)
示例 2:全屏斜向工牌(姓名·工号)
const waterMark = {
visible: true,
items: [{
type: 'tile',
text: '张三 · 工号 10086',
angle: -32,
textSize: 13,
textColor: '#55FFFFFF',
gapX: 200,
gapY: 110
}]
}
Ba-WatermarkView 方法
setWatermarkTexts / updateConfig / getConfig / setVisible / setTextColor / setBackgroundColor / setTextSize / setPosition / clearWatermark / refresh
Ba-CameraView 水印方法
| 方法 | 说明 |
|---|---|
| setWaterMark(cb, cfg) | 写入成片烧录样式;cfg 也可写成 { waterMark: {...} } |
| clearWaterMark(cb) | 清除成片烧录 |
九、权限说明
| 权限 | 用途 |
|---|---|
| CAMERA | 预览 / 拍照 / 录像 |
| RECORD_AUDIO | 有声录像(可选;拒绝则降级无声) |
| VIBRATE | 拍摄完成震动(可选) |
| FLASHLIGHT | 闪光灯(部分机型) |
十、示例 Demo
| 入口 | 路径 | 说明 |
|---|---|---|
| 总览 | pages/camera/index |
功能列表 |
| 快速开始 · 全屏 | pages/camera/cameraQuick |
全屏预览 · 拍照 · 翻转;设置 scene=quick |
| 快速开始 · 半屏 | pages/camera/cameraQuickHalf |
半屏嵌入;设置 scene=quickHalf |
| 综合效果 | pages/camera/camera |
宽高比 / 闪光灯 / 变焦 / 拍照·录像 / 微距 / 对焦框;scene=full |
| 拍照 | pages/camera/cameraPhoto |
成片比例 scaleFlag;scene=photo;设置页仅拍照参数 |
| 裁剪 | pages/camera/camera2 |
拍后裁剪库与比例;scene=crop;设置页仅裁剪参数 |
| 水印 | pages/camera/camera3 |
时间地点 / 斜向工牌 / 自定义多行;默认 9:16;scene=watermark;样式在上方,进页项在「更多参数」 |
| 水印相机 | pages/camera/cameraWm |
数字时钟水印 + 地点/滤镜/模板;默认 9:16;scene=wmCamera |
| 微距 | pages/camera/cameraMacro |
微距近拍;scene=macro |
| 录像 | pages/camera/cameraVideo |
录像专用;scene=video |
| 视频流 | pages/camera/cameraStream |
LIVE 预览流 · 截图 · 可选落盘;scene=stream |
| 人脸框 | pages/camera/cameraFace |
检测框 · 自动/手动抓脸 · 整帧+人脸九宫格;scene=face |
| 初始化 / 设置 | pages/camera/settings?scene=&mode= |
mode=init 进页前可改绑定项;mode=runtime 页内⚙绑定项只读 |
- 各场景配置独立(
ba_camera_demo_settings__{scene}) - 进页绑定(前摄 / targetSize / jpegQuality / 启动微距):总览 → 初始化页修改 →「进入演示」;页内只读
- 运行参数(缩放手势、震动、镜像、比例、水印等):页内 ⚙ 可改,返回即刷新;多数场景在 「更多参数」 折叠区
- 预览宽高比:优先布局 +
scaleFlag:0;Demo 可用顶栏 / 设置切换(见上文「推荐:预览比例与成片对齐」)
十一、常见问题
Q:为什么必须用 nvue?
A:原生组件在 vue 页面中叠层与事件兼容性较差,推荐 nvue。
Q:业务接入预览比例怎么设?一定要传 9:16 吗?
A:多数情况建议 full(scaleFlag: 0),用布局控制相机容器比例,成片跟预览框对齐。只有预览框也做成同一比例、且必须强制成片为该比时,再传 scaleFlag / scaleW/H。详见「推荐:预览比例与成片对齐」。
Q:设置了 full,页面容器是正方形或 9:16 会怎样?
A:full 表示成片跟 当前 PreviewView 实际大小 对齐,不额外固定裁切。容器是方 → 成片取景≈方;容器是 9:16 → 成片≈竖条。不会因为写了 full 就强制全屏。
Q:设置了 9:16,但界面相机仍是正方形?
A:预览方、成片可能按 9:16 再裁(竖图),所见非所得。请让容器比例与拍照参数一致,或改用 full + 正确布局。
Q:水印预览有了,成片没有 / 不一致?
A:预览与烧录是两条通道。推荐同一份 cfg:watermarkView.updateConfig(cfg) + cameraView.setWaterMark(cfg),之后 takePicture 可不传 waterMark。仍兼容旧写法:拍时再传 { waterMark: cfg }。水印组件须叠在相机区域内,勿盖整页。
Q:预览宽高比 Demo 怎么设?水印默认多少?
A:Demo 在对应场景设置里改 previewAspect,或顶栏切换。水印 / 水印相机默认 **9:16**(恢复默认后);其它多数场景默认 full。各场景配置独立,可删存储键 ba_camera_demo_settings__{scene}。
Q:点击对焦白框位置不对 / 看不见?
A:对焦框由原生 FocusRingView 绘制(与点击同一坐标系)。不要用 nvue position:fixed 再叠一层,坐标系会错位;请使用最新 AAR(对焦框在 PreviewView 外层兄弟叠层)。
Q:裁剪取消后 takePicture 一直没回调?连点快门挂住?
A:已修复。取消裁剪会回调 ok:false, msg:'用户取消裁剪';连点会立刻回调 正在拍照,请稍候(不会覆盖上一笔)。裁剪过程中也会挡住再次拍照,直到完成或取消。
Q:jpegQuality / setJpegQuality 改了,这张照片怎么没变?
A:正常。质量在绑定相机时定死,运行中只记偏好,下次绑定才生效。要用指定质量进页,请设 load.jpegQuality;运行中改完可切一次前后摄或重新进入页面。不会为改质量立刻 rebind,以免拍照报 Not bound。
Q:拍照报 Not bound to a valid Camera [ImageCapture]?
A:多为绑定后再次 rebind 导致。当前版本改 jpegQuality 不会立刻重绑;请使用最新 AAR。若仍出现,检查是否在录像/切换过程中连续调用会解绑的接口。
Q:提示当前设备不支持录像?
A:部分机型无法同时绑定预览+拍照+录像,会自动降级;已加强 SD 回退。若仍失败,可在设置里把录像画质改为 SD 再试。
Q:❀ 小花是什么?
A:微距模式开关,开启后会拉近焦距便于近拍。
Q:右下角按钮是什么?
A:前后摄像头翻转;录像中不可切换。
Q:facingFront 改了不生效?
A:属启动配置,需重新进入页面;演示里可在设置中修改后返回,必要时再进一次该场景页。
Q:录像中切换摄像头失败?
A:设计如此,请先 stopRecord 再切换。
Q:人脸框开了,录像或四开失败?
A:人脸依赖 ImageAnalysis。建议 setSessionMode({ mode:'photo' }) 后再 startFaceDetect。与录像同时开时,部分机型无法绑定「预览+拍照+录像+分析」,会降级或启用人脸失败。
Q:预览有人脸框,captureFace 却超时失败?
A:框来自检测,抓图要再等一帧做 YUV→Bitmap 裁切。默认 waitMs:3500 内会重试;仍失败可增大 waitMs,或确认未在录像中、分析流已成功绑定(startFaceDetect 返回 ok)。
Q:抓到的人脸不如 takePicture 清晰?
A:正常。captureFace 来自低分辨率分析流(默认约 480×360 量级),用于框选/留证;高清成片请用 takePicture。
Q:裁剪比例不生效 / 成片比预览多一圈?
A:原生已用 ViewPort 对齐预览与成片。scaleFlag:0(推荐默认)时成片即预览可见区域。若要固定比例,请同时约束预览框并传对应 scaleFlag / scaleW/scaleH。isCrop: true 走的是拍后交互式裁剪库,与 ViewPort 自动对齐是两回事。

收藏人数:
购买(
试用
使用 HBuilderX 导入示例项目
赞赏(0)
下载 14513
赞赏 6
下载 13536
赞赏 1
赞赏
京公网安备:11010802035340号