HarmonyOS 有没有高效的从glTexture中读取数据到CPU的方法?

HarmonyOS
5天前
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
FengTianYa

请参照以下ImageReceiver代码:

import XComponentContext from "../interface/XComponentContext"
import Logger from '../model/Logger';
import common from '@ohos.app.ability.common';
import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
import { camera } from '@kit.CameraKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { image } from '@kit.ImageKit';

let cameraManager: camera.CameraManager;
const TAG: string = 'Xcomponent indexPage';
let previewSession: camera.CaptureSession | undefined = undefined;
let cameraInput : camera.CameraInput;
let previewOutput : camera.PreviewOutput;

@Component
export struct KComponentView {
  private xComponentContext: XComponentContext | undefined = undefined;

  private surfaceId: bigint = BigInt('0');
  private context : common.BaseContext = getContext(this)
  mXComponentController: XComponentController = new XComponentController()
  @State permissionCamera:Boolean = false;
  @Prop xComponentWidth: number = 384;
  @Prop xComponentHeight: number = 450;
  private appContext: common.Context = getContext(this);
  atManager = abilityAccessCtrl.createAtManager();

  aboutToDisappear(): void {
    this.releaseCamera();
  }
  async releaseCamera() {
    if (cameraInput) {
      cameraInput.close()
    }
    if (previewOutput) {
      previewOutput.release()
    }

    if (previewSession) {
      previewSession.release()
    }
  }

  async requestPermissionsFn() {
    Logger.info(TAG, `requestPermissionsFn entry`);
    try {
      this.atManager.requestPermissionsFromUser(this.appContext, [
        'ohos.permission.CAMERA',
        'ohos.permission.MICROPHONE',
        'ohos.permission.READ_MEDIA',
        'ohos.permission.WRITE_MEDIA'
      ]).then(() => {
        Logger.info(TAG, `request Permissions success!`);
        this.createPreview();
        this.permissionCamera = true;
      })
    } catch (err) {
      Logger.info(TAG, `requestPermissionsFromUser call Failed! error: ${err.code}`);
      this.permissionCamera = false;
    }
  }

  async createImageReceiver(): Promise<string> {
    const size :image.Size = {
      height: 400,
      width: 640
    }
    const receiver: image.ImageReceiver = image.createImageReceiver(size, 4, 8);
    receiver.on('imageArrival', () => {
      receiver.readLatestImage((err, nextImage
        : image.Image) => {
        if (err || nextImage === undefined) {
          return;
        }
        nextImage.getComponent(image.ComponentType.JPEG, async (err, imgComponent: image.Component) => {
          console.log("==========> getImageData")
          nextImage.release();
        })
      })
    })
    return receiver.getReceivingSurfaceId();
  }

  async createPreview(): Promise<void> {

    // 创建CameraManager对象
    cameraManager= camera.getCameraManager(this.context);
    if (!cameraManager) {
      console.error("camera.getCameraManager error");
      return;
    }
    // 监听相机状态变化
    cameraManager.on('cameraStatus', (err: BusinessError, cameraStatusInfo: camera.CameraStatusInfo) => {
      console.info(`camera : ${cameraStatusInfo.camera.cameraId}`);
      console.info(`status: ${cameraStatusInfo.status}`);
    });

    // 获取相机列表
    let cameraArray: Array<camera.CameraDevice> = cameraManager.getSupportedCameras();
    if (cameraArray.length <= 0) {
      console.error("cameraManager.getSupportedCameras error");
      return;
    }

    for (let index = 0; index < cameraArray.length; index++) {
      console.info('cameraId : ' + cameraArray[index].cameraId); // 获取相机ID
      console.info('cameraPosition : ' + cameraArray[index].cameraPosition); // 获取相机位置
      console.info('cameraType : ' + cameraArray[index].cameraType); // 获取相机类型
      console.info('connectionType : ' + cameraArray[index].connectionType); // 获取相机连接类型
    }

    // 创建相机输入流
    try {
      cameraInput = cameraManager.createCameraInput(cameraArray[0]);
    } catch (error) {
      let err = error as BusinessError;
      console.error('Failed to createCameraInput errorCode = ' + err.code);
    }
    if (cameraInput === undefined) {
      return;
    }

    // 监听cameraInput错误信息
    let cameraDevice: camera.CameraDevice = cameraArray[0];
    cameraInput.on('error', cameraDevice, (error: BusinessError) => {
      console.error(`Camera input error code: ${error.code}`);
    })

    // 打开相机
    await cameraInput.open();

    // 获取相机设备支持的输出流能力
    let cameraOutputCap: camera.CameraOutputCapability = cameraManager.getSupportedOutputCapability(cameraArray[0], camera.SceneMode.NORMAL_PHOTO);
    if (!cameraOutputCap) {
      console.error("cameraManager.getSupportedOutputCapability error");
      return;
    }
    console.info("outputCapability: " + JSON.stringify(cameraOutputCap));

    let previewProfilesArray: Array<camera.Profile> = cameraOutputCap.previewProfiles;
    if (!previewProfilesArray) {
      console.error("createOutput previewProfilesArray == null || undefined");
    }

    // 创建预览输出流,其中参数 surfaceId 参考上文 XComponent 组件,预览流为XComponent组件提供的surface
    let previewProfilesObj: camera.Profile = previewProfilesArray[0];
    previewProfilesArray.forEach(profile => {
      let supportSize = profile.size
      Logger.debug("----choose Supported profile: size1-- " + supportSize.width + " " + supportSize.height + " type:" + profile.format)
      if (supportSize.width == this.xComponentWidth && supportSize.height == this.xComponentHeight
      ) {
        // 选择1920x1080的profile
        previewProfilesObj = profile;
        Logger.debug("----choose Supported profile: size-- " + supportSize.width + " " + supportSize.height + " type:" + profile.format)
      }
      Logger.debug("Supported profile: size-- " + supportSize.width + " " + supportSize.height + " type:" + profile.format)
    });

    try {
      previewOutput = cameraManager.createPreviewOutput(previewProfilesObj, this.surfaceId.toString());
      console.log(this.surfaceId.toString());
    } catch (error) {
      let err = error as BusinessError;
      console.error(`Failed to create the PreviewOutput instance. error code: ${err.code}`);
    }
    if (previewOutput === undefined) {
      return;
    }
    // 监听预览输出错误信息
    previewOutput.on('error', (error: BusinessError) => {
      console.error(`Preview output error code: ${error.code}`);
    });
    try {
      previewSession = cameraManager.createCaptureSession();
    } catch (error) {
      let err = error as BusinessError;
      console.error('Failed to create the session instance. errorCode = ' + err.code);
    }
    if (previewSession === undefined) {
      return;
    }
    // 监听session错误信息
    previewSession.on('error', (error: BusinessError) => {
      console.error(`Capture session error code: ${error.code}`);
    });

    // 开始配置会话
    try {
      previewSession.beginConfig();
    } catch (error) {
      let err = error as BusinessError;
      console.error('Failed to beginConfig. errorCode = ' + err.code);
    }

    // 向会话中添加相机输入流
    try {
      previewSession.addInput(cameraInput);
    } catch (error) {
      let err = error as BusinessError;
      console.error('Failed to addInput. errorCode = ' + err.code);
    }

    // 向会话中添加预览输出流
    try {
      previewSession.addOutput(previewOutput);
    } catch (error) {
      let err = error as BusinessError;
      console.error('Failed to addOutput(previewOutput). errorCode = ' + err.code);
    }
    await previewSession.commitConfig();
    await previewSession.start();
  }

  build() {
    Column() {
      Column() {
        XComponent({
          id: 'xcomponentId',
          type: XComponentType.SURFACE,
          libraryname: 'nativerender',
          controller: this.mXComponentController
        })
          .onLoad(async (xComponentContext) => {
            this.xComponentContext = xComponentContext as XComponentContext;
            this.mXComponentController.setXComponentSurfaceSize({ surfaceWidth: this.xComponentWidth, surfaceHeight: this.xComponentHeight });
            const xcId = this.mXComponentController.getXComponentSurfaceId();
            const imgSurfaceId : string = await this.createImageReceiver();
            const imgSurfaceIdInt = parseInt(imgSurfaceId);
            this.surfaceId = this.xComponentContext.toImageReceiver(imgSurfaceIdInt);
            this.requestPermissionsFn();
          })
          .onDestroy(() => {
            console.log('onDestroy');
          })
          .id("xcomponent")
          .margin(5)
          .layoutWeight(1)
      }
      .layoutWeight(1)
      .width('90%')
    }
    .width('100%')
    .height('100%')
  }
}
分享
微博
QQ
微信
回复
5天前
相关问题
ArkTS有没有读取ini类?
380浏览 • 1回复 待解决
HarmonyOS有没有中文编码方法
120浏览 • 1回复 待解决
HarmonyOS 有没有实现后台模糊方法
253浏览 • 1回复 待解决
HarmonyOS ArkTS有没有TS替代方法
206浏览 • 1回复 待解决
读取数据文件方法有哪些
620浏览 • 1回复 待解决
有没有给canvas设置ColorFilter方法
762浏览 • 1回复 待解决
HarmonyOS 有没有对UI添加水印方法
219浏览 • 1回复 待解决