HarmonyOS鸿蒙Next中如何解决组件宽高过长导致组件截图失败的问题

HarmonyOS鸿蒙Next中如何解决组件宽高过长导致组件截图失败的问题

【问题现象】

使用componentSnapshot.get接口进行组件截图,组件内容过长会出现截图失败,问题现象和代码如下图,图中是通过输入框数字控制List组件中的图片数量,然后对List组件进行截图:

点击放大

点击放大

【背景知识】

  • 组件截图:本模块提供获取组件截图的能力,包括已加载的组件的截图和没有加载的组件的截图。组件截图只能够截取组件大小的区域,如果组件的绘制超出了它的区域,或子组件的绘制超出了父组件的区域,这些在组件区域外绘制的内容不会在截图中呈现。兄弟节点堆叠在组件区域内,截图不会显示兄弟组件。
  • SnapshotOptionsSnapshotOptionsscale属性指定截图时图形侧绘制pixelmap的缩放比例,但是请注意比例过大时截图时间会变长,或者截图可能会失败。不要截取过大尺寸的图片,截图不建议超过屏幕尺寸的大小。当要截取的图片目标长宽超过底层限制(8192px)时,截图会返回失败,不同设备的底层限制不同。

【定位思路】

分析组件内容过长对组件截图的影响:

  1. 增加输入图片的数量,扩大组件长度,进行测试。观察发现当输入的图片数量大于等于7时,此时组件高度大于8192px,组件截图失败;

点击放大

点击放大

  1. 问题代码没有设置SnapshotOptionsscale属性,所以默认为1。

【解决方案】

当组件宽高较大(大于8192px),组件截图可以通过设置snapshotoptionsscale缩放压缩图像,具体可以通过onAreaChange监听组件区域变化动态调整scale

代码示例如下:

// 根据组件的宽高与8192px的比例动态调整scale的值
Column({ space: 10 }) {
  ForEach(this.imageArray, (item: string) => {
    Column() {
      Text(item).fontSize(20)
    }
    .height(200).width(200).backgroundColor(Color.Yellow).justifyContent(FlexAlign.Center)
  })
}
.id('ComponentShot')
.onAreaChange((oldValue: Area, newValue: Area) => {
  let comHeight = vp2px(newValue.height as number)
  let comWidth = vp2px(newValue.width as number)
  if (comHeight >= comWidth) {
    this.ratio = comHeight <= 8192 ? 1 : 8191 / comHeight
  } else {
    this.ratio = comWidth <= 8192 ? 1 : 8191 / comWidth
  }
  console.log(`getComponentShot, Component height: ${comHeight}px, width: ${comWidth}px, ratio: ${this.ratio}`)
})

// 在调用组件贴图时传入合适的缩放比例
componentSnapshot.get(componentId, (error: Error, pixmap: image.PixelMap) => {}, {scale: this.ratio})

【总结】

在使用组件截图时,需要关注截图组件的宽高是否过长,采用合适的缩放比例可以有效避免截图失败或者不完整的情况。


更多关于HarmonyOS鸿蒙Next中如何解决组件宽高过长导致组件截图失败的问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS鸿蒙Next中如何解决组件宽高过长导致组件截图失败的问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


当组件宽高超过8192px时,截图会失败。可以通过设置SnapshotOptionsscale属性来缩放图像,避免截图失败。使用onAreaChange监听组件区域变化,动态调整scale值。代码示例如下:

Column({ space: 10 }) {
  ForEach(this.imageArray, (item: string) => {
    Column() {
      Text(item).fontSize(20)
    }
    .height(200).width(200).backgroundColor(Color.Yellow).justifyContent(FlexAlign.Center)
  })
}
.id('ComponentShot')
.onAreaChange((oldValue: Area, newValue: Area) => {
  let comHeight = vp2px(newValue.height as number)
  let comWidth = vp2px(newValue.width as number)
  if (comHeight >= comWidth) {
    this.ratio = comHeight <= 8192 ? 1 : 8191 / comHeight
  } else {
    this.ratio = comWidth <= 8192 ? 1 : 8191 / comWidth
  }
  console.log(`getComponentShot, Component height: ${comHeight}px, width: ${comWidth}px, ratio: ${this.ratio}`)
})

componentSnapshot.get(componentId, (error: Error, pixmap: image.PixelMap) => {}, {scale: this.ratio})
回到顶部