HarmonyOS 关于图片裁切问题

当使用CameraKit进行拍照,然后通过如下代码获取图片buffer,但是通过photo: camera.Photo获取的图片宽高为[25165824,1]。

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> => {
    let buffer: ArrayBuffer = component.byteBuffer
    this.savePicture(buffer, imageObj)
  })
})
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

目前按照4:3拍照比例进行拍照,当切换至1:1之后,只进行遮挡,然后通过裁剪进行解决,下列代码是将拍照获取的buffer转为pixelmap,然后通过pixelmap.crop进行裁切,裁切完成之后,在转为buffer写入相册。

/*
 * PixelMap转Buffer
 * */
PixelMapToBuffer(pixelMap: image.PixelMap, width: number, height: number): ArrayBuffer{
  //缓存区大小 = width * height * 4
  let bufferLength = width * height * 4
  const buffer: ArrayBuffer = new ArrayBuffer(bufferLength)
  pixelMap.readPixelsToBufferSync(buffer)
  return buffer
}

/*
* Buffer转PixelMap
* */
async BufferToPixelMap(buffer: ArrayBuffer, width: number, height: number): Promise<image.PixelMap>{
  let sourceOptions: image.SourceOptions = {
    sourceDensity: 0, // 在不确定当前密度时传0
    sourcePixelFormat: image.PixelMapFormat.RGBA_8888,
    sourceSize: {width: width, height: height}
  }
  let imageSource: image.ImageSource = image.createImageSource(buffer, sourceOptions)
  let opts: image.InitializationOptions = {
    editable: false,
    pixelFormat: image.PixelMapFormat.RGBA_8888,
    size: {width: width, height: height}
  }
  return await imageSource.createPixelMap(opts)
}

try {
  //6144 8192
  let pixelMap = await this.pixelMapBufferConvertUtil.BufferToPixelMap(buffer, 6144, 8192)
  if (!pixelMap) {
    LoggerJoy.error(`CameraPage--> occur error when crop photo!`)
    return undefined
  }
  LoggerJoy.info(`CameraPage--> the image size is [${size.width},${size.height}]`)//25165824,1
  pixelMap.cropSync({x: 0, y: 0, size: {width: 6144, height: 8192}})
  return this.pixelMapBufferConvertUtil.PixelMapToBuffer(pixelMap, 6144, 8192)
} catch (error) {
  let err = error as BusinessError
  LoggerJoy.error(`CameraPage--> occur error when crop photo, the error code: ${err.code}, error message: ${err.message}`)
  return undefined
}
  • 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.

目前所遇到的问题是拍照获取的图片宽高为[25165824,1],裁切之后的图片在相册无法预览。

HarmonyOS
2024-12-23 16:26:06
浏览
收藏 0
回答 1
回答 1
按赞同
/
按时间
aquaa

请参考以下示例:

setPhotoOutputCb(photoOutput: camera.PhotoOutput) {
  //设置回调之后,调用photoOutput的capture方法,就会将拍照的buffer回传到回调中
  photoOutput.on('photoAvailable', (errCode: BusinessError, photo: camera.Photo): void => {
    console.info(`CameraDemo getPhoto start. err: ${JSON.stringify(errCode)}`);
    if (errCode || photo === undefined || photo.main === undefined) {
      console.error('CameraDemo getPhoto failed');
      return;
    }
    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;
        this.buffer = buffer;
        //创建imageSource
        const imageSource = image.createImageSource(buffer)
        //创建PixelMap
        this.finalPixelMap = await imageSource.createPixelMap()
        await this.finalPixelMap.getImageInfo().then((imageInfo: image.ImageInfo) => {
          if (imageInfo == undefined) {
            console.error("Failed to obtain the image pixel map information.");
          } else {
            console.info(`裁剪前information:${JSON.stringify(imageInfo)}`);
          }
        })
        let region: image.Region = { x: 0, y: 0, size: { height: 500, width: 500 } };
        this.finalPixelMap.crop(region).then(async () => {
          console.info('Sucessed in setting crop.');
          if (this.finalPixelMap != undefined) {
            await this.finalPixelMap.getImageInfo().then((imageInfo: image.ImageInfo) => {
              if (imageInfo == undefined) {
                console.error("Failed to obtain the image pixel map information.");
              } else {
                console.info(`裁剪后information:${JSON.stringify(imageInfo)}`);
              }
            })
          }
        }).catch((err: BusinessError) => {
          console.error('Failed to crop pixelmap.');
        })
      } else {
        console.error('CameraDemo byteBuffer is null');
        return;
      }
    });
  });
}

// PixelMap转Buffer
async packingPixelMap2Jpg(pixelMap: PixelMap): Promise<ArrayBuffer> {
  // 创建ImagePacker实例
  const imagePackerApi = image.createImagePacker();
  // 设置打包参数
  // format:图片打包格式,只支持 jpg 和 webp
  // quality:JPEG 编码输出图片质量
  // bufferSize:图片大小,默认 10M
  const packOpts: image.PackingOption = { format: "image/jpeg", quality: 100 };
  let imageBuffer: ArrayBuffer = new ArrayBuffer(1);
  try {
  // 图片压缩或重新打包
  imageBuffer = await imagePackerApi.packing(pixelMap, packOpts);
} catch (err) {
  console.error(`Invoke packingPixelMap2Jpg failed, err: ${JSON.stringify(err)}`);
}
return imageBuffer;
}

//保存至相册
async imageWriteAlbumExample2(pixelMap:image.PixelMap) {
  let imagePackerApi = image.createImagePacker();
  let packOpts: image.PackingOption = { format: "image/jpeg", quality: 98 };
  imagePackerApi.packing(pixelMap, packOpts).then(async (buffer: ArrayBuffer) => {
    try {
      const context = getContext(this)
      let helper = photoAccessHelper.getPhotoAccessHelper(context)
      let uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'png')
      let file = await fs.open(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)
      // 写入文件 注意加一个packing的过程
      await fs.write(file.fd, buffer);
      // 关闭文件
      await fs.close(file.fd);
      promptAction.showToast({
        message: '已保存至相册',
        duration: 2500
      });
    } catch (error) {
      console.error("error is " + JSON.stringify(error))
    }
  }).catch((error: BusinessError) => {
    console.error('Failed to pack the image. And the error is: ' + error);
  })
}
  • 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.
分享
微博
QQ
微信
回复
2024-12-23 19:30:07


相关问题
HarmonyOS 图片裁切处理
574浏览 • 1回复 待解决
HarmonyOS 如何将图片裁切成圆形
705浏览 • 1回复 待解决
HarmonyOS Canvas中关于绘制图片问题
1024浏览 • 1回复 待解决
关于Image组件加载网络图片问题
1673浏览 • 1回复 待解决
关于导入图片的使用权限和问题
2635浏览 • 1回复 待解决
关于图片组件的问题有知道的吗?
1867浏览 • 1回复 待解决
HarmonyOS .clip矩形裁切无法生效
826浏览 • 1回复 待解决
HarmonyOS 关于图片浏览大图
816浏览 • 1回复 待解决
HarmonyOS 关于crash问题
1315浏览 • 1回复 待解决
HarmonyOS关于navigation问题
1467浏览 • 1回复 待解决
HarmonyOS 关于手势问题
725浏览 • 1回复 待解决
HarmonyOS 关于cookie问题
918浏览 • 1回复 待解决
HarmonyOS 关于加固问题
738浏览 • 1回复 待解决
HarmonyOS 关于应用的启动图片设置
502浏览 • 1回复 待解决
HarmonyOS 关于弹窗相关问题
679浏览 • 1回复 待解决
HarmonyOS 关于lottie加载问题
861浏览 • 1回复 待解决
HarmonyOS 关于获取userAgent问题
850浏览 • 1回复 待解决
HarmonyOS 关于json解析问题
732浏览 • 1回复 待解决
HarmonyOS 关于Map语法问题
1579浏览 • 1回复 待解决
HarmonyOS 关于包体积问题
858浏览 • 1回复 待解决