HarmonyOS【相机服务】连续拍照场景如何将多张照片合成一张?

HarmonyOS【相机服务】连续拍照场景如何将多张照片合成一张?

HarmonyOS
2024-08-12 15:29:16
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
FengTianYa

可以使用 canvas 合并图片:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-drawing-customization-on-canvas-V5

图片合并 demo,以两张图片竖向排放为例。

// 图片合并 使用 canvas 
public static async imageMerge(img1: PixelMap, img2: PixelMap) { 
  // 获取照片信息 
  let info1: image.ImageInfo = await img1.getImageInfo(); 
  let info2: image.ImageInfo = await img2.getImageInfo(); 
  let twidth = info1.size.width + info2.size.width; 
  let theight = info1.size.height + info2.size.height 
  // 创建离屏的 canvas 
  let offCanvas2D = new OffscreenCanvas(twidth, theight); 
  let offContext = offCanvas2D.getContext("2d"); 
  offContext.drawImage(img1, 0, 0, info1.size.width, info1.size.height); 
  offContext.drawImage(img2, 0, info1.size.height, info2.size.width, info2.size.height); 
  // 获取合并后的 img pixel 
  let finalPixel = offContext.getPixelMap(0, 0, twidth, theight); 
  return finalPixel; 
} 
public static async saveImage(img: PixelMap, path: string) { 
  let imgPacker = image.createImagePacker(); 
  let imgBuf = await imgPacker.packing(img, {format: "image/jpeg", quality: 100}); 
  let fd = fileIo.openSync(path, fileIo.OpenMode.CREATE | fileIo.OpenMode.READ_WRITE).fd; 
  fileIo.writeSync(fd, imgBuf); 
}

相机页面做三件事情

1. 定义 pixelMaps 接受多张图片

2. Camera kit 中 photoAvailable 事件中,喂入拍照图片数据给 pixelMaps

3. 设置一个合并按钮,调用合并图片方法

变量:

@State pixelMaps: Array<image.PixelMap | undefined> = new Array();

回调函数:

setPhotoOutputCb(photoOutput: camera.PhotoOutput) { 
  //设置回调之后,调用photoOutput的capture方法,就会将拍照的buffer回传到回调中 
  photoOutput.on('photoAvailable', (errCode: BusinessError, photo: camera.Photo): void => { 
    let imageObj = photo.main; 
    imageObj.getComponent(image.ComponentType.JPEG, async (errCode: BusinessError, component: image.Component): Promise<void> => { 
      console.info('CameraDemo getComponent start'); 
      if (errCode || component === undefined) { 
        console.error('CameraDemo getComponent failed'); 
        return; 
      } 
      let buffer: ArrayBuffer; 
      if (component.byteBuffer) { 
        buffer = component.byteBuffer; 
        let sourceOptions: image.SourceOptions = { 
          sourceDensity: 0, // 在不确定当前密度时传0 
          sourcePixelFormat: image.PixelMapFormat.RGBA_8888, 
          sourceSize: this.imageSize 
        } 
        let imageSource: image.ImageSource = image.createImageSource(buffer, sourceOptions); 
        let opts: image.InitializationOptions = { 
          editable: false, 
          pixelFormat: image.PixelMapFormat.RGBA_8888, 
          size: this.imageSize 
        } 
        let pixelMap = await imageSource.createPixelMap(opts); 
        this.pixelMaps[this.pixelMaps.length++] = pixelMap; 
      } else { 
        console.error('CameraDemo byteBuffer is null'); 
        return; 
      } 
    }); 
  }); 
}

按钮:

Button('合并') 
  .onClick(async () => { 
    if (this.pixelMaps.length > 2 && this.pixelMaps[0] != undefined && this.pixelMaps[1] != undefined) { 
      let imgm = await ImageUtil.imageMerge(this.pixelMaps[0], this.pixelMaps[1]); 
      ImageUtil.saveImage(imgm, getContext(this).cacheDir + "/test.jpg"); 
    } 
  })

imageMerge 方法画布大小 twidth、theight 可自行配置。

分享
微博
QQ
微信
回复
2024-08-13 12:06:35
相关问题
如何将一张图片转化为PixelMapElement
10023浏览 • 1回复 待解决
如何吸取一张图片的色值?
409浏览 • 1回复 待解决
如何保存一张PNG图片到相册中
1854浏览 • 1回复 待解决
如何连续获取相机预览流数据
702浏览 • 1回复 待解决
HarmonyOS 拉起相机拍照
368浏览 待解决
HarmonyOS 相机拍照模糊
513浏览 • 0回复 待解决
HarmonyOS如何控制相机拍照
173浏览 • 0回复 待解决