自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何調(diào)用設(shè)備攝像頭進(jìn)行拍照、預(yù)覽并將拍攝結(jié)果保存在媒體庫中(Camera)

開發(fā) 后端
調(diào)用設(shè)備攝像頭進(jìn)行拍照、預(yù)覽是許多應(yīng)用開發(fā)過程中都需要的功能。在拍照完成時(shí)顯示照片預(yù)覽圖可以確認(rèn)拍攝的照片是否達(dá)到預(yù)期,本例將為大家介紹如何實(shí)現(xiàn)上述功能。

想了解更多關(guān)于開源的內(nèi)容,請(qǐng)?jiān)L問:

51CTO 開源基礎(chǔ)軟件社區(qū)

https://ost.51cto.com

場(chǎng)景說明

調(diào)用設(shè)備攝像頭進(jìn)行拍照、預(yù)覽是許多應(yīng)用開發(fā)過程中都需要的功能。在拍照完成時(shí)顯示照片預(yù)覽圖可以確認(rèn)拍攝的照片是否達(dá)到預(yù)期,本例將為大家介紹如何實(shí)現(xiàn)上述功能。

效果呈現(xiàn)

本例效果如下:

拍照

預(yù)覽

運(yùn)行環(huán)境

本例基于以下環(huán)境開發(fā),開發(fā)者也可以基于其他適配的版本進(jìn)行開發(fā)。

  • IDE:DevEco Studio 4.0.0.201 Beta1
  • SDK:Ohos_sdk_public 4.0.7.5 (API Version 10 Beta1)

實(shí)現(xiàn)思路

本例使用@ohos.multimedia.camera接口實(shí)現(xiàn)相機(jī)示例的主要功能:拍照、預(yù)覽;

  • 拍照:XComponent組件負(fù)責(zé)繪制攝像頭畫面呈現(xiàn)的窗口,其onload事件調(diào)用cameraModel.ts的initCamera方法初始化相機(jī)功能輸出畫面信息。拍照動(dòng)作使用Image組件實(shí)現(xiàn),其onclick事件調(diào)用cameraModel.ts的takepicture方法開始拍照。
  • 預(yù)覽:返回相機(jī)界面點(diǎn)擊底部左側(cè)預(yù)覽圖可進(jìn)入相冊(cè)應(yīng)用,可以在其中查看照片和錄制的視頻。

開發(fā)步驟

申請(qǐng)所需權(quán)限:
在model.json5中添加以下配置:

"requestPermissions": [
      {
        "name": "ohos.permission.CAMERA"http://允許應(yīng)用使用相機(jī)拍攝照片和錄制視頻
      },
      {
        "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)用讀寫用戶外部存儲(chǔ)中的媒體文件信息
      },
      {
        "name": "ohos.permission.READ_MEDIA"http://允許應(yīng)用讀取用戶外部存儲(chǔ)中的媒體文件信息
      }
    ]

創(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初始化相機(jī)功能
            })
            .width('100%')
            .height('100%')
            .margin({ bottom: 152 })
            Column() {
        }
        .width('97%')
        .height('100%')

初始化相機(jī)功能initCamera方法通過創(chuàng)建相機(jī)管理器實(shí)例cameraMgr來創(chuàng)建畫面輸出對(duì)象previewOutput。cameraMgr再通過創(chuàng)建CaptureSession實(shí)例來配置會(huì)話,完成相機(jī)功能的準(zhǔn)備工作。

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實(shí)例receiver
    this.receiver = image.createImageReceiver(
      cameraWH.width,
      cameraWH.height,
      FOUR,
      EIGHT
    );
    //接收?qǐng)D片時(shí)注冊(cè)回調(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);//獲取相機(jī)管理器實(shí)例
    } 
    this.camerasArray = this.cameraMgr.getSupportedCameras();//獲取支持指定的相機(jī)設(shè)備對(duì)象
    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);//查詢相機(jī)設(shè)備支持的輸出能力
    let previewProfile = this.capability.previewProfiles[0];
	//通過相機(jī)管理器創(chuàng)建預(yù)覽輸出對(duì)象
    this.previewOutput = this.cameraMgr.createPreviewOutput(
      previewProfile,												
      surfaceId												//surfaceId從XComponent組件獲取
    );
    let rSurfaceId = await this.receiver.getReceivingSurfaceId();//獲取一個(gè)surface id供其他組件使用
    let photoProfile = this.capability.photoProfiles[0];
	//通過相機(jī)管理器創(chuàng)建照片輸出對(duì)象
    this.photoOutPut = this.cameraMgr.createPhotoOutput(
      photoProfile,
      rSurfaceId										//rSurfaceId通過構(gòu)造函數(shù)中定義的圖像接收類receiver獲取
    );
    this.capSession = this.cameraMgr.createCaptureSession();//創(chuàng)建CaptureSession實(shí)例
    this.capSession.beginConfig();//開始配置會(huì)話
    this.capSession.addInput(this.cameraInput);//將cameraInput加入會(huì)話
    this.capSession.addOutput(this.previewOutput);//將預(yù)覽輸出加入會(huì)話
    this.capSession.addOutput(this.photoOutPut);//將照片輸出加入會(huì)話
    await this.capSession.commitConfig();//提交配置信息
    await this.capSession.start();//開始輸出
  }

點(diǎn)擊按鈕進(jìn)行拍照,拍照按鈕通過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()開始拍照
                } 
              })

拍照功能具體實(shí)現(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類型資源,將拍攝到的照片寫入到這個(gè)資源中去。

//model/MediaModel.ts中定義的負(fù)責(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)前時(shí)間
    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)容,請(qǐng)?jiān)L問:

51CTO 開源基礎(chǔ)軟件社區(qū)

https://ost.51cto.com

責(zé)任編輯:jianghua 來源: 51CTO 開源基礎(chǔ)軟件社區(qū)
相關(guān)推薦

2023-02-26 22:06:22

Electron瀏覽器開發(fā)

2011-09-13 15:51:11

PhoneGap AP

2020-06-04 10:59:10

JavaScript開發(fā)技術(shù)

2016-02-22 10:30:38

AngularJSHTML5攝像頭

2022-05-12 09:25:19

Python播放視頻攝像頭

2018-06-20 11:54:54

2024-11-29 16:51:18

2009-08-21 17:11:05

C#攝像頭

2011-12-19 16:09:32

PhoneGap APCamera

2011-09-08 13:53:20

Linux攝像頭

2013-03-21 09:56:09

2021-03-11 10:21:55

特斯拉黑客網(wǎng)絡(luò)攻擊

2014-07-16 13:36:30

MotionLinux監(jiān)控

2022-04-15 11:30:59

代碼,Python保存視頻

2023-03-23 15:57:07

鴻蒙系統(tǒng)API基本用法

2022-08-01 17:53:36

漏洞網(wǎng)絡(luò)攻擊

2017-06-20 11:45:52

2023-03-24 10:28:27

2011-04-25 09:16:10

Windows 8

2012-06-23 20:13:44

HTML5
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)