想了解更多關(guān)于開源的內(nèi)容,請訪問:
51CTO 開源基礎(chǔ)軟件社區(qū)
https://ost.51cto.com
調(diào)用設(shè)備攝像頭進行拍照、預(yù)覽是許多應(yīng)用開發(fā)過程中都需要的功能。在拍照完成時顯示照片預(yù)覽圖可以確認拍攝的照片是否達到預(yù)期,本例將為大家介紹如何實現(xiàn)上述功能。
本例效果如下:
拍照 | 預(yù)覽 |
本例基于以下環(huán)境開發(fā),開發(fā)者也可以基于其他適配的版本進行開發(fā)。
本例使用@ohos.multimedia.camera接口實現(xiàn)相機示例的主要功能:拍照、預(yù)覽;
申請所需權(quán)限:
在model.json5中添加以下配置:
"requestPermissions": [ { "name": "ohos.permission.CAMERA"http://允許應(yīng)用使用相機拍攝照片和錄制視頻 }, { "name": "ohos.permission.MICROPHONE"http://允許應(yīng)用使用麥克風(fēng) }, { "name": "ohos.permission.MEDIA_LOCATION"http://允許應(yīng)用訪問用戶媒體文件中的地理位置信息 }, { "name": "ohos.permission.WRITE_MEDIA"http://允許應(yīng)用讀寫用戶外部存儲中的媒體文件信息 }, { "name": "ohos.permission.READ_MEDIA"http://允許應(yīng)用讀取用戶外部存儲中的媒體文件信息 } ]
創(chuàng)建繪制組件XComponent以輸出攝像頭獲取的畫面,其綁定的onload方法中設(shè)定了畫幅的大小。
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 });//設(shè)置surface大小 this.surfaceId = this.mXComponentController.getXComponentSurfaceId(); this.currentModel = CameraMode.modePhoto; this.cameraModel.initCamera(this.surfaceId); //調(diào)用model/cameraModel.ts初始化相機功能 }) .width('100%') .height('100%') .margin({ bottom: 152 }) Column() { } .width('97%') .height('100%')
初始化相機功能initCamera方法通過創(chuàng)建相機管理器實例cameraMgr來創(chuàng)建畫面輸出對象previewOutput。cameraMgr再通過創(chuàng)建CaptureSession實例來配置會話,完成相機功能的準備工作。
import image from '@ohos.multimedia.image';//自@ohos.multimedia.image引入image,提供圖片處理效果...private receiver: image.ImageReceiver = undefined;//圖像接收類,用于獲取組件surface id,接收最新的圖片和讀取下一張圖片...constructor() { this.mediaModel = MediaModel.getMediaInstance();//通過調(diào)用model/MediaModel.ets中的方法創(chuàng)建mediaInstance類mediaModel //創(chuàng)建ImageReceiver實例receiver this.receiver = image.createImageReceiver( cameraWH.width, cameraWH.height, FOUR, EIGHT ); //接收圖片時注冊回調(diào) this.receiver.on('imageArrival', () => { //從ImageReceiver讀取下一張圖片 this.receiver.readNextImage((err, image) => { if (err || image === undefined) { return; } //根據(jù)圖像的組件類型從圖像中獲取組件緩存 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();//獲取支持指定的相機設(shè)備對象 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);//查詢相機設(shè)備支持的輸出能力 let previewProfile = this.capability.previewProfiles[0]; //通過相機管理器創(chuàng)建預(yù)覽輸出對象 this.previewOutput = this.cameraMgr.createPreviewOutput( previewProfile, surfaceId //surfaceId從XComponent組件獲取 ); let rSurfaceId = await this.receiver.getReceivingSurfaceId();//獲取一個surface id供其他組件使用 let photoProfile = this.capability.photoProfiles[0]; //通過相機管理器創(chuàng)建照片輸出對象 this.photoOutPut = this.cameraMgr.createPhotoOutput( photoProfile, rSurfaceId //rSurfaceId通過構(gòu)造函數(shù)中定義的圖像接收類receiver獲取 ); this.capSession = this.cameraMgr.createCaptureSession();//創(chuàng)建CaptureSession實例 this.capSession.beginConfig();//開始配置會話 this.capSession.addInput(this.cameraInput);//將cameraInput加入會話 this.capSession.addOutput(this.previewOutput);//將預(yù)覽輸出加入會話 this.capSession.addOutput(this.photoOutPut);//將照片輸出加入會話 await this.capSession.commitConfig();//提交配置信息 await this.capSession.start();//開始輸出 }
點擊按鈕進行拍照,拍照按鈕通過Image組件呈現(xiàn),其綁定的onClick方法調(diào)用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();//調(diào)用model/cameraModel.takePicture()開始拍照 } })
拍照功能具體實現(xiàn):
拍照:
async takePicture(): Promise<void> { //設(shè)置拍照相關(guān)參數(shù) let photoSettings = { rotation: this.imageRotation, quality: camera.QualityLevel.QUALITY_LEVEL_MEDIUM, location: { // 位置信息,經(jīng)緯度 latitude: 12.9698, longitude: 77.75, altitude: 1000, }, mirror: false, }; await this.photoOutPut.capture(photoSettings); AppStorage.Set('isRefresh', true); }
保存圖片:
saveImage方法使用MediaModel中的createAndGetUri方法創(chuàng)建Image類型資源,將拍攝到的照片寫入到這個資源中去。
//model/MediaModel.ts中定義的負責(zé)保存圖片的相關(guān)方法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()}`;//獲取當(dāng)前時間 let displayName: string = `${info.prefix}${name}${info.suffix}`; //獲取公共目錄路徑。 let publicPath: string = await this.mediaLibraryTest.getPublicDirectory( info.directory );//通過引用自@ohos.multimedia.mediaLibrary的mediaLibraryTest類創(chuàng)建媒體資源,其中定義了媒體類型、名稱、路徑。 let fileAsset: mediaLibrary.FileAsset = await this.mediaLibraryTest.createAsset( mediaType,//根據(jù)傳入函數(shù)createAndGetUri的mediaType參數(shù)決定創(chuàng)建什么類型的媒體資源 displayName, publicPath ); return fileAsset; } async getFdPath(fileAsset: mediaLibrary.FileAsset): Promise<number> { let fd: number = await fileAsset.open('Rw');//打開當(dāng)前文件 return fd; }...async saveImage(buffer: ArrayBuffer, img: image.Image): Promise<void> { this.fileAsset = await this.mediaModel.createAndGetUri(mediaLibrary.MediaType.IMAGE); //通過調(diào)用MediaModel中的方法創(chuàng)建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函數(shù) await img.release(); if (this.takePictureHandle) { this.takePictureHandle(this.photoPath); } }
想了解更多關(guān)于開源的內(nèi)容,請訪問:
51CTO 開源基礎(chǔ)軟件社區(qū)
https://ost.51cto.com
本文鏈接:http://www.www897cc.com/showinfo-26-50742-0.html如何調(diào)用設(shè)備攝像頭進行拍照、預(yù)覽并將拍攝結(jié)果保存在媒體庫中(Camera)
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com
下一篇: 水波紋動畫開發(fā)(ArkUI)