調用手機的相機功能並實現拍照和錄像是很多APP與插件都必不可少的一個功能,今天智密科技就來分享一下如何基於uniapp + vue實現自定義相機界面,並且實現:
1: 自定義拍照
2: 自定義錄像
3: 時長控制
4: 閃光燈控制
本文主要先分享前兩條最基本的功能實現
先看效果:


技術實現
- 開發環境:HbuilderX + nodejs
- 技術框架:uniapp + vue2.x
- 測試環境:App端(Android + IOS)
- 代碼:開源
效果概覽



界面布局
這里主要是以自定義的樣式為主,功能上使用了“智密相冊-自定義相冊相機”插件,插件提供了一個自定義相冊的wrapper控件,因此我們只需要專注於ui即可,布局的代碼如下
<view class="camera-container"> <zhimi_camera_view ref="camera" class="camera-elem"></zhimi_camera_view> <view class="camera-methods"> <view class="camera-methods-item is-left" @click="doSwitchFlashLight()"> <image v-if="useFlashLight" class="camera-methods-item-image" src="../../static/icon_flash_start.png"></image> <image v-else class="camera-methods-item-image" src="../../static/icon_flash_stop.png"></image> </view> <view class="camera-methods-capture"> <view class="camera-methods-capture-elem" :class="{ 'camera-methods-capture-elem-recording': recording }" @click="doAction" ></view> </view> <view class="camera-methods-item is-right" @click="doSwitchCamera()"> <image class="camera-methods-item-image" src="../../static/icon_switch_camear.png"></image> </view> </view> <text class="fit-left-btn" @click="doBack">退出</text> <view class="fit-right-btn"> <text class="fit-right-btn-item" :class="{ 'fit-right-btn-item-is-active': cameraMode == 1 }" @click="setWrapperType(1)">拍照</text> <text class="fit-right-btn-item" :class="{ 'fit-right-btn-item-is-active': cameraMode == 2 }" @click="setWrapperType(2)">錄像</text> </view> </view>
這里有個重點,由於我們去掉了原生的標題欄,這需要在pages.json中進行配置,具體配置如下
{ "path":"pages/index/camera", "style": { "navigationStyle":"custom" } },
相機控件初始化
在這里我們主要是操作原生控件“zhimi_camera_view”提供的方法,首先我們需要設置回調事件以及相機的類型,比如攝像還是錄像,前置還是后置相機
設置回調事件
let wrapper = this.$refs.camera wrapper.setEventCallback(({ type, data }) => { console.log(type, data) });
設置相機類型
let wrapper = this.$refs.camera // 設置相機模式 1 = 拍照模式,2 = 錄像模式 wrapper.changeType(1)
設置前后置攝像頭
let wrapper = this.$refs.camera // 是否使用前置相機 true = 開啟,false = 關閉 wrapper.useFrontCamera(false)
串聯起來完整的初始化相機控件的代碼就是這樣的
let wrapper = this.$refs.camera wrapper.setEventCallback(({ type, data }) => { console.log(type, data) }); wrapper.changeType(1) // 設置拍照 wrapper.useFrontCamera(false) // 設置后置攝像頭
拍照錄像與閃光燈控制
完成了相機的初始化之后,我們需要做一些業務上面的,比如拍照,錄像,閃光燈開關等功能
閃光燈控制
let wrapper = this.$refs.camera // 是否開啟閃光燈 true = 開啟,false = 關閉 wrapper.flashLightAction(true) // 開啟閃光燈
拍照
let wrapper = this.$refs.camera wrapper.takePhotoAction();
錄像
let wrapper = this.$refs.camera // true = 開始錄像, false = 結束錄像 wrapper.takeVideoAction(true);
對於閃光燈而言,開關閃光燈是控制閃光燈是否持續開啟,也就是手電筒模式,而不是拍照的時候才閃的,效果上參考下面2張對比圖


無閃光燈(無光點) 有閃光燈(有光點)
獲取拍照/錄像結果
在前面我們已經通過setEventCallback綁定了回調事件,一般來說拍照/錄像完成之后會通過回調事件反饋拍照錄像結果,具體代碼如下
cameraEventHanlder (res) { let { type, data } = res switch (type){ // 拍照模式返回圖片路徑數據 case 'imageType': // 注意:此處返回的為平台路徑,前端顯示請加file://前綴 console.log(data) break; // 錄像模式返回視頻路徑數據 case 'videoType': // 注意:此處返回的為平台路徑,前端顯示請加file://前綴 console.log(data) break; default: console.log(data) break; } }
注意看注釋,這里最大的重點是路徑,如果說獲取到的路徑前端需要顯示在界面前面,需要添加file://前綴,比如獲取到的文件路徑如下:
/var/data/Android/Album/timeStamp.png
前端顯示的時候需要這樣寫
<image src="file:///var/data/Android/Album/timeStamp.png"/>
注意這里是3個斜桿,因為安卓這類移動端系統都是基於類unix開發的,因此都是從 / 根開始檢索文件的,所以前端需要使用file協議,並且以/開頭。
插件地址:智密相冊-自定義相冊相機-自由布局相機
