HarmonyOS 双路预览流获取的数据,无法生成一个 pixelMap

1、从双路预览流获取数据,并拷贝生成一个 ArrayBuffer

2、根据这个 ArrayBuffer 生成一个 pixelMap,但是报错

HarmonyOS
2024-12-20 16:15:35
1366浏览
收藏 0
回答 1
回答 1
按赞同
/
按时间
Excelsior_abit

参考demo:

import camera from '@ohos.multimedia.camera';
import image from '@ohos.multimedia.image';
import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
import common from '@ohos.app.ability.common';
import fs from '@ohos.file.fs';

import {BusinessError} from '@ohos.base';
@Entry
@Component
struct Index {
  @State message: string = 'Hello World'
  private mXComponentController: XComponentController = new XComponentController;
  private surfaceId: string = '-1';
  @State imgUrl: PixelMap | undefined = undefined;
  private context: ESObject = undefined
  private previewProfilesObj2: camera.Profile | undefined = undefined;
  private receiver: image.ImageReceiver | undefined = undefined;
  private receiver1: image.ImageReceiver | undefined = undefined;




  aboutToAppear() {
    //申请权限
    let context = getContext() as common.UIAbilityContext;
    abilityAccessCtrl.createAtManager().requestPermissionsFromUser(context, ['ohos.permission.CAMERA']).then(() => {
      this.mXComponentController.setXComponentSurfaceSize({ surfaceWidth: 1920, surfaceHeight: 1080 });
      // 获取Surface ID
      this.surfaceId = this.mXComponentController.getXComponentSurfaceId();
      this.createDualChannelPreview(this.surfaceId);
    });
    console.info(`surfaceId=${this.surfaceId}`);
  }

  async createDualChannelPreview(XComponentSurfaceId: string): Promise<void> {
    let cameraManager = await camera.getCameraManager(getContext() as ESObject);
    let camerasDevices: Array<camera.CameraDevice> = cameraManager.getSupportedCameras(); // 获取支持的相机设备对象

    // 获取支持的模式类型
    let sceneModes: Array<camera.SceneMode> = cameraManager.getSupportedSceneModes(camerasDevices[0]);
    let isSupportPhotoMode: boolean = sceneModes.indexOf(camera.SceneMode.NORMAL_PHOTO) >= 0;
    if (!isSupportPhotoMode) {
      console.error('photo mode not support');
      return;
    }
    // 获取profile对象
    let profiles: camera.CameraOutputCapability = cameraManager.getSupportedOutputCapability(camerasDevices[0]); // 获取对应相机设备profiles
    let previewProfiles: Array<camera.Profile> = profiles.previewProfiles;

    // 预览流1
    let previewProfilesObj: camera.Profile = previewProfiles[0];

    // 预览流2
    this.previewProfilesObj2 = previewProfiles[0];

    let size:image.Size = {
      height: this.previewProfilesObj2.size.height,
      width: this.previewProfilesObj2.size.width
    }
    this.receiver= image.createImageReceiver(size, image.ImageFormat.JPEG, 8)
    this.receiver1= image.createImageReceiver(size, image.ImageFormat.JPEG, 8)
    // 创建 预览流1 输出对象
    let previewOutput: camera.PreviewOutput = cameraManager.createPreviewOutput(previewProfilesObj, XComponentSurfaceId);
    // 创建 预览流2 输出对象
    let imageReceiverSurfaceId: string = await this.receiver.getReceivingSurfaceId();
    console.log("imageReceiverSurfaceId-------------"+imageReceiverSurfaceId)

    let previewOutput2: camera.PreviewOutput = cameraManager.createPreviewOutput(this.previewProfilesObj2, imageReceiverSurfaceId);
    // 创建cameraInput对象
    let cameraInput: camera.CameraInput = cameraManager.createCameraInput(camerasDevices[0]);
    // 打开相机
    await cameraInput.open();
    // 会话流程
    let captureSession: camera.CaptureSession = cameraManager.createCaptureSession();
    // 开始配置会话
    captureSession.beginConfig();
    // 把CameraInput加入到会话
    captureSession.addInput(cameraInput);
    // 把 预览流1 加入到会话
    captureSession.addOutput(previewOutput);
    // 把 预览流2 加入到会话
    captureSession.addOutput(previewOutput2);
    // 提交配置信息
    await captureSession.commitConfig();
    // 会话开始
    await captureSession.start();
    this.onImageArrival(this.receiver);
  }
  a(){

  }
  async onImageArrival(receiver: image.ImageReceiver): Promise<void> {
    receiver.on('imageArrival', () => {
      console.error("imageArrival callback");
      receiver.readNextImage((err, nextImage: image.Image) => {
        let a = nextImage.format
        nextImage.getComponent(image.ComponentType.JPEG, async (err, imgComponent: image.Component) => {
          if (err || imgComponent === undefined) {
            return;
          }
          this.saveImageToFile(imgComponent.byteBuffer);
          if (imgComponent.byteBuffer as ArrayBuffer) {
            let sourceOptions: image.SourceOptions = {
              sourceDensity: 120,
              sourcePixelFormat: 8, // NV21
              sourceSize: {
                height: this.previewProfilesObj2!.size.height,
                width: this.previewProfilesObj2!.size.width
              },
            }
            let imageResource = image.createImageSource(imgComponent.byteBuffer, sourceOptions);
            let imagePackerApi = image.createImagePacker();
            let packOpts: image.PackingOption = { format: "image/jpeg", quality: 98 };
            const filePath: string = getContext().cacheDir + "/image.jpg";
            let file = fs.openSync(filePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);
            imagePackerApi.packToFile(imageResource, file.fd, packOpts).then(() => {
              console.error('pack success: ' + filePath);
            }).catch((error: BusinessError) => {
              console.error('Failed to pack the image. And the error is: ' + error);
            })
            imageResource.createPixelMap({editable:true,desiredPixelFormat:image.PixelMapFormat.NV21}).then((res)=>{
              this.imgUrl = res;
            });
          } else {
            return;
          }
          nextImage.release();
        })
      })
    })
  }
  saveImageToFile(data: ArrayBuffer) {
    const context = getContext(this);
    let filePath = context.tempDir + "/test.jpg";
    console.info("path is " + filePath);
    let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
    fs.write(file.fd, data, (err, writeLen) => {
      if (err) {
        console.info("write failed with error message: " + err.message + ", error code: " + err.code);
      } else {
        console.info("write data to file succeed and size is:" + writeLen);
        fs.closeSync(file);
      }
    });
    // context.tempDir + "/test.jpg" 对应绝对路径 /data/app/el2/100/base/com.example.image_example/haps/Packer/temp/test.jpg (也可通过hdc shell 查询对应目录)
    // hdc file recv /data/app/el2/100/base/com.example.image_example/haps/Packer/temp/test.jpg D:\ (获取文件到本地,查看保存结果)
  }
  build() {
    Column() {

      // 创建XComponent
      XComponent({
        id: '',
        type: 'surface',
        libraryname: '',
        controller: this.mXComponentController
      })
        .onLoad(() => {
          // 设置Surface宽高(1920*1080),预览尺寸设置参考前面 previewProfilesArray 获取的当前设备所支持的预览分辨率大小去设置
          // this.mXComponentController.setXComponentSurfaceSize({ surfaceWidth: 1920, surfaceHeight: 1080 });
          // 获取Surface ID
          this.surfaceId = this.mXComponentController.getXComponentSurfaceId();
          this.createDualChannelPreview(this.surfaceId);
        })
        .width('800px')
        .height('1280px')

      Row() {
        // 将编辑好的pixelMap传递给状态变量imagePixelMap后,通过Image组件进行渲染
        Image(this.imgUrl).objectFit(ImageFit.None)
      }.width('100%').height('50%').backgroundColor('#F0F0F0')
    }
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
  • 170.
  • 171.
  • 172.
  • 173.
  • 174.
分享
微博
QQ
微信
回复
2024-12-20 17:36:18
相关问题
如何实现预览+录制功能
1911浏览 • 1回复 待解决
如何连续获取相机预览数据
1402浏览 • 1回复 待解决
如何随机生成一个汉字?
1013浏览 • 1回复 待解决
HarmonyOS 怎么把两PixelMap合成一个
1095浏览 • 2回复 待解决
HarmonyOS 需要一个图片预览组件
983浏览 • 1回复 待解决
如果写一个多级获取数据问题?
3988浏览 • 1回复 待解决