想了解更多關于開源的內容,請訪問:
51CTO 開源基礎軟件社區
https://ost.51cto.com
調用設備攝像頭進行拍照、預覽是許多應用開發過程中都需要的功能。在拍照完成時顯示照片預覽圖可以確認拍攝的照片是否達到預期,本例將為大家介紹如何實現上述功能。
本例效果如下:
拍照 | 預覽 |
本例基于以下環境開發,開發者也可以基于其他適配的版本進行開發。
本例使用@ohos.multimedia.camera接口實現相機示例的主要功能:拍照、預覽;
申請所需權限:
在model.json5中添加以下配置:
"requestPermissions": [ { "name": "ohos.permission.CAMERA"http://允許應用使用相機拍攝照片和錄制視頻 }, { "name": "ohos.permission.MICROPHONE"http://允許應用使用麥克風 }, { "name": "ohos.permission.MEDIA_LOCATION"http://允許應用訪問用戶媒體文件中的地理位置信息 }, { "name": "ohos.permission.WRITE_MEDIA"http://允許應用讀寫用戶外部存儲中的媒體文件信息 }, { "name": "ohos.permission.READ_MEDIA"http://允許應用讀取用戶外部存儲中的媒體文件信息 } ]
創建繪制組件XComponent以輸出攝像頭獲取的畫面,其綁定的onload方法中設定了畫幅的大小。
build() { Column() { Title() .visibility(this.isTitleShow ? Visibility.Visible : Visibility.None) Stack({ alignContent: Alignment.Bottom }) { Stack({ alignContent: Alignment.TopStart }) { XComponent({ id: 'componentId', type: 'surface', controller: this.mXComponentController //將控制器綁定至XComponent組件 }) .onLoad(() => { this.mXComponentController.setXComponentSurfaceSize({ surfaceWidth: 640, surfaceHeight: 480 });//設置surface大小 this.surfaceId = this.mXComponentController.getXComponentSurfaceId(); this.currentModel = CameraMode.modePhoto; this.cameraModel.initCamera(this.surfaceId); //調用model/cameraModel.ts初始化相機功能 }) .width('100%') .height('100%') .margin({ bottom: 152 }) Column() { } .width('97%') .height('100%')
初始化相機功能initCamera方法通過創建相機管理器實例cameraMgr來創建畫面輸出對象previewOutput。cameraMgr再通過創建CaptureSession實例來配置會話,完成相機功能的準備工作。
import image from '@ohos.multimedia.image';//自@ohos.multimedia.image引入image,提供圖片處理效果...private receiver: image.ImageReceiver = undefined;//圖像接收類,用于獲取組件surface id,接收最新的圖片和讀取下一張圖片...constructor() { this.mediaModel = MediaModel.getMediaInstance();//通過調用model/MediaModel.ets中的方法創建mediaInstance類mediaModel //創建ImageReceiver實例receiver this.receiver = image.createImageReceiver( cameraWH.width, cameraWH.height, FOUR, EIGHT ); //接收圖片時注冊回調 this.receiver.on('imageArrival', () => { //從ImageReceiver讀取下一張圖片 this.receiver.readNextImage((err, image) => { if (err || image === undefined) { return; } //根據圖像的組件類型從圖像中獲取組件緩存 image.getComponent(FOUR, (errMsg, img) => { if (errMsg || img === undefined) { return; } let buffer = new ArrayBuffer(FOUR_THOUSAND_AND_SIXTY_NINE); if (img.byteBuffer) { buffer = img.byteBuffer; } this.saveImage(buffer, image); }); }); }); }async initCamera(surfaceId: string): Promise<void> { ... try { this.cameraMgr = camera.getCameraManager(globalThis.cameraContext);//獲取相機管理器實例 } this.camerasArray = this.cameraMgr.getSupportedCameras();//獲取支持指定的相機設備對象 if (this.camerasArray.length === 0) { return; } let mCamera = this.camerasArray[0]; this.cameraInput = this.cameraMgr.createCameraInput(mCamera); this.cameraInput.open(); this.capability = this.cameraMgr.getSupportedOutputCapability(mCamera);//查詢相機設備支持的輸出能力 let previewProfile = this.capability.previewProfiles[0]; //通過相機管理器創建預覽輸出對象 this.previewOutput = this.cameraMgr.createPreviewOutput( previewProfile, surfaceId //surfaceId從XComponent組件獲取 ); let rSurfaceId = await this.receiver.getReceivingSurfaceId();//獲取一個surface id供其他組件使用 let photoProfile = this.capability.photoProfiles[0]; //通過相機管理器創建照片輸出對象 this.photoOutPut = this.cameraMgr.createPhotoOutput( photoProfile, rSurfaceId //rSurfaceId通過構造函數中定義的圖像接收類receiver獲取 ); this.capSession = this.cameraMgr.createCaptureSession();//創建CaptureSession實例 this.capSession.beginConfig();//開始配置會話 this.capSession.addInput(this.cameraInput);//將cameraInput加入會話 this.capSession.addOutput(this.previewOutput);//將預覽輸出加入會話 this.capSession.addOutput(this.photoOutPut);//將照片輸出加入會話 await this.capSession.commitConfig();//提交配置信息 await this.capSession.start();//開始輸出 }
點擊按鈕進行拍照,拍照按鈕通過Image組件呈現,其綁定的onClick方法調用takePicture方法開始拍照。
Image(this.getCameraIcon()) .size({ width: 64, height: 64 }) .margin({ left: 10 }) .id('camera') .onClick(() => { if (this.currentModel === CameraMode.modePhoto) { prompt.showToast({ message: '拍照中...', duration: 200 }); this.cameraModel.takePicture();//調用model/cameraModel.takePicture()開始拍照 } })
拍照功能具體實現:
拍照:
async takePicture(): Promise<void> { //設置拍照相關參數 let photoSettings = { rotation: this.imageRotation, quality: camera.QualityLevel.QUALITY_LEVEL_MEDIUM, location: { // 位置信息,經緯度 latitude: 12.9698, longitude: 77.75, altitude: 1000, }, mirror: false, }; await this.photoOutPut.capture(photoSettings); AppStorage.Set('isRefresh', true); }
保存圖片:
saveImage方法使用MediaModel中的createAndGetUri方法創建Image類型資源,將拍攝到的照片寫入到這個資源中去。
//model/MediaModel.ts中定義的負責保存圖片的相關方法async createAndGetUri(mediaType: mediaLibrary.MediaType): Promise<mediaLibrary.FileAsset> { let dateTimeUtil: DateTimeUtil = new DateTimeUtil(); let info: FileInfo = this.getInfoFromMediaType(mediaType); let name: string = `${dateTimeUtil.getDate()}_${dateTimeUtil.getTime()}`;//獲取當前時間 let displayName: string = `${info.prefix}${name}${info.suffix}`; //獲取公共目錄路徑。 let publicPath: string = await this.mediaLibraryTest.getPublicDirectory( info.directory );//通過引用自@ohos.multimedia.mediaLibrary的mediaLibraryTest類創建媒體資源,其中定義了媒體類型、名稱、路徑。 let fileAsset: mediaLibrary.FileAsset = await this.mediaLibraryTest.createAsset( mediaType,//根據傳入函數createAndGetUri的mediaType參數決定創建什么類型的媒體資源 displayName, publicPath ); return fileAsset; } async getFdPath(fileAsset: mediaLibrary.FileAsset): Promise<number> { let fd: number = await fileAsset.open('Rw');//打開當前文件 return fd; }...async saveImage(buffer: ArrayBuffer, img: image.Image): Promise<void> { this.fileAsset = await this.mediaModel.createAndGetUri(mediaLibrary.MediaType.IMAGE); //通過調用MediaModel中的方法創建Image類型資源 this.photoPath = this.fileAsset.uri; this.fd = await this.mediaModel.getFdPath(this.fileAsset); await fileIo.write(this.fd, buffer);//將拍攝的照片寫入到Mediamodel傳回的資源中去 await this.fileAsset.close(this.fd);//釋放open函數 await img.release(); if (this.takePictureHandle) { this.takePictureHandle(this.photoPath); } }
想了解更多關于開源的內容,請訪問:
51CTO 開源基礎軟件社區
https://ost.51cto.com
本文鏈接:http://www.tebozhan.com/showinfo-26-50742-0.html如何調用設備攝像頭進行拍照、預覽并將拍攝結果保存在媒體庫中(Camera)
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com
上一篇: 覓伊 APP 崩了引熱議 官方緊急修復
下一篇: 水波紋動畫開發(ArkUI)