daShangDao_scanBook/uni_modules/ima-camera-view/readme.md

374 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 原生自定义相机拍照、视频录制 ima-camera-view
`原生自定义相机拍照、视频录制 ima-camera-view`是基于原生相机开发的UTS插件支持`相机拍照`、`视频录制`
、可实现`点击聚焦`、`手势缩放`、
`自定义布局`、`自定义蒙版`(用于人脸拍照,身份证拍照等)。
## ⚠️注意️
由于之前技术选型不支持继续扩展相机的新特性,`本插件ima-camera-view继续维护只修复现存的一些bug不再新增新功能`
建议使用ima-camerax-view这个相机组件插件[ima-camerax-view 地址](https://ext.dcloud.net.cn/plugin?name=ima-camerax-view)
如果不追求如:**超广角镜头切换0.5x`changeWideAngle`**、**按倍率缩放(`setCameraZoom`,如 0.5 / 1.0 / 2.0**、**多摄逻辑镜头切换**、
**Camera2 白平衡 / HDR / 曝光补偿**、**录像进度(`onVideoTakenProgress`)与设备方向变化(`onOrientationChanged`)回调**等新特性的话,扔建议继续使用本插件。
- `ima-camerax-view【新插件】`[插件地址](https://ext.dcloud.net.cn/plugin?name=ima-camerax-view)
- `ima-camera-view【本插件】`[插件地址](https://ext.dcloud.net.cn/plugin?name=ima-camera-view)
- `ima-camerax-view【新插件】``ima-camera-view【本插件】`组件 API 保持基本一致,便于从 CameraView 版平滑迁移
## 支持功能
- 打开、关闭摄像头预览
- 拍照、快照拍照
- 录制视频、快照录制视频
- 设置摄像头缩放级别
- 设置相机白平衡
- 设置相机HDR
- 设置相机曝光
- 设置摄像头方向
- 设置闪光灯模式
- 设置相机使用设备方向
- 设置相机网格及颜色
- 设置音频(录制视频时)
- 设置圆角、圆预览(可自定义)
- 外接摄像头预览方向修正(`previewRotation`Android
- 设置拍照、录制视频的声音(可自定义)
- 蓝牙自拍杆(可自定义)
- 手机快捷键(可自定义)
## 自定义调整
- 自定义调整页面地址:`uni_modules/ima-camera-view/utssdk/app-android/index.vue`
- 蓝牙自拍杆、手机快捷键的自定义,可以参考文件中的`shortcutListener`方法
- 设置拍照、录制视频的声音,可以参考文件中的`photoSound`、`videoSound`方法
## 需要权限
- 摄像头、音频、文件读取、文件写入、震动
```text
"android.permission.CAMERA",
"android.permission.RECORD_AUDIO",
"android.permission.VIBRATE"
"android.permission.READ_EXTERNAL_STORAGE"
"android.permission.WRITE_EXTERNAL_STORAGE"
```
- 即:在`manifest.json`中的`distribute.android.permissions`加入
```text
// 拍摄照片和视频时需要
<uses-permission android:name="android.permission.CAMERA" />
// 拍摄视频时需要Audio.ON默认
<uses-permission android:name="android.permission.RECORD_AUDIO" />
// 读取拍照、录像文件文件时需要
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
// 报错拍照、录像文件文件时需要(默认保存到沙盒缓存)
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
// 震动权限
<uses-permission android:name="android.permission.VIBRATE" />
```
## 快门声音素材
- 将需要的快门声音放在`uni_modules/ima-camera-view/utssdk/app-android/assets`下即可
- [熊猫办公](https://www.tukuppt.com/yinxiaomuban/kuaimenshengyin.html)
- [站长素材](https://sc.chinaz.com/tag_yinxiao/kuaimen.html)
## 使用示例【此示例的代码只实现了`相机拍照`的逻辑,更多示例请导入项目】
- 新建一个`camera.nvue`的文件
- ⚠️注意️:只能在`.nvue`、`.uvue`的文件后缀下才生效,不支持`.vue`
```nvue
<template>
<view class="ima-camera" :style="{ width: windowWidth, height: windowHeight }">
<ima-camera-view
ref="cameraRef"
class="camera-view"
:style="{ width: windowWidth + 'px', height: windowHeight + 'px' }"
flash="on"
@onPictureTaken="onPictureTaken"
onFocusStart="onFocusStart"
/>
<view class="camera-menu">
<!--返回键-->
<cover-image @tap="back" class="camera-menu-button back" src="/static/camera/back.png" />
<!--快门键-->
<cover-image
@tap="takePhoto"
class="camera-menu-button shutter"
src="/static/camera/shutter.png"
/>
<!--反转键-->
<cover-image @tap="flip" class="camera-menu-button flip" src="/static/camera/flip.png" />
</view>
</view>
</template>
<script>
let _this = null
export default {
data() {
return {
windowWidth: '', //屏幕可用宽度
windowHeight: '', //屏幕可用高度
facing: 'back'
}
},
onLoad() {
_this = this
this.initCamera()
},
methods: {
//初始化相机
initCamera() {
console.log('初始化相机')
uni.getSystemInfo({
success: (res) => {
_this.windowWidth = res.windowWidth
_this.windowHeight = res.windowHeight
}
})
},
onFocusStart(e) {
console.log('聚焦', e)
},
takePhoto() {
console.log('拍照', this.facing)
this.$refs.cameraRef.takePhoto()
},
//返回
back() {
console.log('返回上一页', this.facing)
uni.navigateBack()
},
//反转
flip() {
console.log('镜头反转', this.facing)
this.facing = this.facing === 'back' ? 'front' : 'back'
this.$refs.cameraRef.changeFacing(this.facing)
},
onPictureTaken(e) {
console.log('拍照结果', e.detail)
_this.snapshotsrc = e.detail?.path || ''
_this.getTakenRes()
uni.navigateBack()
},
//设置
getTakenRes() {
console.log('返回结果给上一页')
let pages = getCurrentPages()
let prevPage = pages[pages.length - 2] //上一个页面
//直接调用上一个页面的setImage()方法,把数据存到上一个页面中去
prevPage.$vm.setImage({ path: _this.snapshotsrc })
}
}
}
</script>
<style lang="scss">
.ima-camera {
justify-content: center;
align-items: center;
.camera-view {
width: 100%;
background: #111;
}
.camera-menu {
position: absolute;
left: 0;
bottom: 0;
width: 750rpx;
height: 180rpx;
z-index: 98;
align-items: center;
justify-content: center;
&-button {
width: 80rpx;
height: 80rpx;
position: absolute;
bottom: 50rpx;
z-index: 99;
align-items: center;
justify-content: center;
}
.back {
left: 30rpx;
}
.shutter {
width: 130rpx;
height: 130rpx;
left: 310rpx;
bottom: 25rpx;
}
.flip {
right: 30rpx;
}
}
}
</style>
```
## 外接摄像头方向修正Android
适用于**无内置摄像头**或外接 USB 摄像头的设备(如横屏平板、工控一体机)。当物理安装的摄像头与屏幕方向不一致,导致预览画面旋转 90° 等情况时,可通过 `previewRotation` 固定修正预览与拍照方向。
### 使用方式
**方式一:属性(推荐)**
```nvue
<ima-camera-view
ref="cameraRef"
:previewRotation="90"
:previewCornerRadiusRate="0.5"
facing="front"
/>
```
**方式二:方法动态调整**
```javascript
this.$refs.cameraRef.changePreviewRotation(90) // 顺时针 90°
this.$refs.cameraRef.changePreviewRotation(-90) // 逆时针 90°等价 270°
```
### 参数说明
| 取值 | 说明 |
|------|------|
| `0` | 不修正(默认) |
| `90` / `-270` | 顺时针旋转 90° |
| `180` / `-180` | 旋转 180° |
| `270` / `-90` | 顺时针旋转 270°逆时针 90° |
### 注意事项
-**`android`** 端生效;与 `orientation`(设备方向跟随)不同,`previewRotation` 用于**固定补偿外接摄像头安装角度**,不随手机旋转而改变。
- 启用非 `0``previewRotation` 后,组件会自动使用 `TextureView` 预览;拍照结果会同步叠加该角度修正。
- 若预览方向仍不对,请依次尝试 `90`、`-90`、`180`,以实际安装方向为准。
- 录像方向暂未做同等叠加修正;若录像也有方向问题,可在业务层二次处理或反馈 issue。
## 常见的比例的定义widthRatioheightRatio
```typescript
// 正方形
AspectRatio.of(1, 1) // 1:1
// 竖屏比例
AspectRatio.of(9, 16) // 9:16 (手机竖屏)
AspectRatio.of(3, 4) // 3:4
AspectRatio.of(2, 3) // 2:3
AspectRatio.of(10, 16) // 10:16 (5:8)
// 横屏比例
AspectRatio.of(16, 9) // 16:9 (宽屏)
AspectRatio.of(4, 3) // 4:3 (传统)
AspectRatio.of(3, 2) // 3:2 (照片)
AspectRatio.of(16, 10) // 16:10 (8:5)
AspectRatio.of(21, 9) // 21:9 (超宽屏)
// 建议比例
const AspectRatios = {
// 1:1 正方形
SQUARE: AspectRatio.of(1, 1),
// 9:16 竖屏(手机默认)
PORTRAIT: AspectRatio.of(9, 16),
// 16:9 横屏
LANDSCAPE: AspectRatio.of(16, 9),
// 3:4 传统照片比例
THREE_FOUR: AspectRatio.of(3, 4),
// 4:3 传统相机比例
FOUR_THREE: AspectRatio.of(4, 3)
}
```
## 不同场景的推荐值tolerance
```typescript
const TOLERANCE = {
STRICT: 0.01.toFloat(), // 非常严格,几乎精确匹配
STANDARD: 0.05.toFloat(), // 标准,推荐使用
FLEXIBLE: 0.1.toFloat(), // 灵活,兼容更多设备
LOOSE: 0.2.toFloat() // 宽松,可能匹配到意外比例
}
```
## Api
| 属性 | 类型 | 默认值 | 说明 | 平台 |
|---------------|-----------------|-------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------|
| widthRatio | Number | 0 | 照片尺寸比率(宽度): 默认全屏若widthRatio为9heightRatio为16则为9:16、widthRatio为3heightRatio为4则为3:4...不建议值过大常用的比例有1:1、3:4、4:3、9:16... | `android` |
| heightRatio | Number | 0 | 照片尺寸比率(高度): 默认全屏若widthRatio为9heightRatio为16则为9:16、widthRatio为3heightRatio为4则为3:4...不建议值过大常用的比例有1:1、3:4、4:3、9:16... | `android` |
| tolerance | Number | 0.1 | 照片尺寸容差值: 建议设为 0.05~0.15,以便稍微兼容不同设备相机实际比例差异 ,值为:01 | `android` |
| whiteBalance | iWhiteBalance | "auto" | 白平衡模式: auto自动、incandescent白炽、fluorescent荧光、daylight日光、cloudy多云 、loudy多云【慎用`兼容1.1.3版本前单词拼错的问题将在1.2.0大版本更新后删除建议1.1.3后的版本使用cloudy`】) | `android` |
| hdr | iHdr | "off" | HDR模式: off关闭、on开启 | `android` |
| facing | iFacing | "back" | 后置、前置摄像头: back(后置摄像头)、front(前置摄像头) | `android` |
| flash | iFlash | "off" | 闪光灯: off(关闭)、on(开启)、auto(自动)、torch(常开) | `android` |
| audio | iAudio | "on" | 音频: on(开启)、off(关闭)、mono(单声道)、stereo(立体声) | `android` |
| orientation | iOrientation | "auto" | 方向: auto(自动)、portrait(竖屏)、landscape(横屏) 【注意:`目前竖屏、横屏拍出来都为竖屏方式,这两个参数的使用效果一致`,为预留参数,为后期做准备】 | `android` |
| grid | iGrid | "off" | 网格: off(关闭)、draw_3X3(3x3)、draw_4x4(4x4)、draw_phi(phi) | `android` |
| gridColor | String | "#808080" | 颜色值: 只支持如:#fff、#ffffff、#......等类型的颜色值 | `android` |
| photoSuffix | iPhotoSuffix | "jpeg" | 照片格式: jpeg、jpg | `android` |
| mode | String | 'picture' | 相机模式: picture(拍照)、video(录视频) | `android` |
| previewCornerRadius | Number | 0 | 预览圆角半径px`previewCornerRadiusRate` 二选一或组合使用 | `android` |
| previewCornerRadiusRate | Number | 0 | 预览圆角比例(相对短边);`0.5` 且预览区域为正方形时为圆形预览 | `android` |
| previewRotation | Number | 0 | 外接摄像头预览/拍照方向修正角度:`0`、`90`、`180`、`270`(支持负值如 `-90`);详见上文「外接摄像头方向修正」 | `android` |
| gallery | Boolean | false | 是否将拍照、录像文件保存到系统相册(可见媒体库) | `android` |
| shutter | Boolean | true | 是否打开拍照声音: true(开启,此时配置`sound`才起作用)、false(关闭) | `android` |
| sound | String | '' | 相机拍照声音文件: 将mp3音频文件放在`uni_modules/ima-camera-view/utssdk/app-android/assets`下即可,为音频文件的名称,如`xxx.mp3`,默认手机原声 | `android` |
| recorder | Boolean | true | 是否打开录像声音: true(开启,此时配置`sound2`才起作用)、false(关闭) | `android` |
| sound2 | String | '' | 相机录像声音文件: 将mp3音频文件放在`uni_modules/ima-camera-view/utssdk/app-android/assets`下即可,为音频文件的名称,如`xxx.mp3`,默认手机原声 | `android` |
| vibrate | Boolean | false | 是否打开拍照震动: true(开启,此时配置`duration`才起作用)、false(关闭) | `android` |
| duration | Number | 300 | 是否打开拍照震动时长单位毫秒ms | `android` |
| shortcut | Boolean | false | 是否开启蓝牙自拍杆、手机快捷键拍照: false(关闭)、true(开启) | `android` |
## 方法
### 共同 方法/* */
| 方法名称 | 说明 | 方法参数 | 平台 |
|-------------------------------------------------------|---------------------------|-----------------------------------------------------------------------------------------------------------------------|-------------|
| open | 打开摄像头预览 | 无 | `android` |
| close | 关闭摄像头预览 | 无 | `android` |
| takePhoto | 拍照(标准拍照流程) | 无 | `android` |
| takeVideo(duration) | 开始录制视频 | duration:拍摄时长单位毫秒ms【0 表示不限制】 | `android` |
| stopVideo | 停止视频录制 | 无 | `android` |
| changeZoom(zoom) | 设置摄像头缩放级别 | zoom:缩放倍数(浮点数) | `android` |
| changeExposure(exposure) | 设置曝光值 | exposure:曝光值(浮点数)【值为:-22默认为0】 | `android` |
| changeWhiteBalance(whiteBalance) | 设置相机白平衡 | whiteBalance:参考`api`中的`whiteBalance`参数 | `android` |
| changeHdr(hdr) | 设置相机HDR | hdr:参考`api`中的`hdr`参数 | `android` |
| changeFacing((facing)) | 设置摄像头方向 | facing:参考`api`中的`facing`参数 | `android` |
| changeFlash(flash) | 设置闪光灯模式 | flash:参考`api`中的`flash`s参数 | `android` |
| changeOrientation(orientation) | 设置相机使用设备方向 | orientation:参考`api`中的`orientation`s参数 | `android` |
| changeGrid(grid,color) | 设置相机网格及颜色 | grid:参考`api`中的`grid`参数, color: 参考`api`中的`gridColor`参数 | `android` |
| changeAudio(audio) | 设置音频 | audio:参考`api`中的`audio`参数 | `android` |
| changeSuffix(suffix) | 设置照片输出格式 | suffix:参考`api`中的`photoSuffix`参数 | `android` |
| changeSizeSelectors(width,height,tolerance) | 设置相机特定比例/分辨率 | width、height、tolerance 参考 `api` 中同名属性;`0` 表示使用屏幕宽高 | `android` |
| changePreviewCorner(radius,radiusRate) | 设置预览圆角 | radius: 圆角 pxradiusRate: 圆角比例(正方形下 `0.5` 为圆形) | `android` |
| changePreviewRotation(degrees) | 设置外接摄像头预览/拍照方向修正 | degrees: `0` / `90` / `180` / `270`(支持负值);仅 Android | `android` |
| changeGallery(gallery) | 是否保存到系统相册 | gallery: `true` / `false` | `android` |
| changeMode(mode) | 设置相机模式 | mode: `picture` / `video`;也可直接使用 `:mode` prop | `android` |
| takePhotoSnapshot | 快照拍照(适用于快速拍照场景) | 无 | `android` |
| takeVideoSnapshot(duration) | 快照方式录制视频 | duration:拍摄时长单位毫秒ms【0 表示不限制】 | `android` |
## 事件
| 事件名称 | 说明 | 回调参数 | 平台 |
|---------------------|---------------|-----------------------------------|-------------|
| onPictureTaken | 拍照返回数据 | ({path,width,height}: any) => {} | `android` |
| onVideoTakenStart | 录制视频开始事件 | () => {} | `android` |
| onVideoTakenEnd | 录制视频结束事件 | ({path,size}: any) => {} | `android` |
| onFocusStart | 自动对焦开始 | ({x,y}: any) => {} | `android` |
| onFocusEnd | 自动对焦结束 | ({x,y,focus}: any) => {} | `android` |
| onOrientationChange | 设备方向变化 | ({angle,orientation,isPortrait,isLandscape}: any) => {} | `android` |
| onCameraOpened | 相机已打开 | (data: any) => {} | `android` |
| onCameraClosed | 相机已关闭 | (data: any) => {} | `android` |
| onCameraError | 相机错误 | ({errorCode,reason,message}: any) => {} | `android` |