往期鸿蒙5.0全套实战文章必看:(文中附带鸿蒙5.0全栈学习资料)
@ohos.arkui.componentSnapshot (组件截图)
本文提供获取组件截图的能力,包括已加载的组件的截图和没有加载的组件的截图。组件截图只能够截取组件大小的区域,如果组件的绘制超出了它的区域,或子组件的绘制超出了父组件的区域,这些在组件区域外绘制的内容不会在截图中呈现。兄弟节点堆叠在组件区域内,截图不会显示兄弟组件。
说明
本模块首批接口从 API version 10 开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。
对于使用XComponent的场景,例如:Video或者相机流媒体展示类组件,不建议使用组件截图相关接口,建议从surface直接获取图片。
如果组件自身内容不能填满组件大小区域,那么剩余位置截图返回的内容为透明像素。如果组件使用了图像效果类属性或其他的效果类属性,则可能产生非用户预期的截图结果。请排查是否需要填充组件透明内容区域,或使用窗口截图替代。
示例效果请以真机运行为准,当前 IDE 预览器不支持。
导入模块
import { componentSnapshot } from '@kit.ArkUI';
componentSnapshot.get
get(id: string, callback: AsyncCallback<image.PixelMap>, options?: SnapshotOptions): void
获取已加载的组件的截图,传入组件的组件标识,找到对应组件进行截图。通过回调返回结果。
说明
截图会获取最近一帧的绘制内容。如果在组件触发更新的同时调用截图,更新的渲染内容不会被截取到,截图会返回上一帧的绘制内容。
元服务API: 从API version 12开始,该接口支持在元服务中使用。
系统能力: SystemCapability.ArkUI.ArkUI.Full
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
id | string | 是 | 目标组件的组件标识 |
callback | AsyncCallback<image.PixelMap> | 是 | 截图返回结果的回调。 |
options12+ | SnapshotOptions | 否 | 截图相关的自定义参数。 |
错误码:
以下错误码的详细介绍。
错误码ID | 错误信息 |
---|---|
401 | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed. |
100001 | Invalid ID. |
示例:
说明
直接使用componentSnapshot可能导致实例不明确的问题,建议使用getUIContext获取UIContext实例,并使用getComponentSnapshot获取绑定实例的componentSnapshot。
import { componentSnapshot } from '@kit.ArkUI';
import { image } from '@kit.ImageKit';
@Entry
@Component
struct SnapshotExample {
@State pixmap: image.PixelMap | undefined = undefined
build() {
Column() {
Row() {
Image(this.pixmap).width(200).height(200).border({ color: Color.Black, width: 2 }).margin(5)
Image($r('app.media.img')).autoResize(true).width(200).height(200).margin(5).id("root")
}
Button("click to generate UI snapshot")
.onClick(() => {
// 建议使用this.getUIContext().getComponentSnapshot().get()
componentSnapshot.get("root", (error: Error, pixmap: image.PixelMap) => {
if (error) {
console.log("error: " + JSON.stringify(error))
return;
}
this.pixmap = pixmap
}, {scale : 2, waitUntilRenderFinished : true})
}).margin(10)
}
.width('100%')
.height('100%')
.alignItems(HorizontalAlign.Center)
}
}
componentSnapshot.get
get(id: string, options?: SnapshotOptions): Promise<image.PixelMap>
获取已加载的组件的截图,传入组件的组件标识,找到对应组件进行截图。通过Promise返回结果。
说明
截图会获取最近一帧的绘制内容。如果在组件触发更新的同时调用截图,更新的渲染内容不会被截取到,截图会返回上一帧的绘制内容。
元服务API: 从API version 12开始,该接口支持在元服务中使用。
系统能力: SystemCapability.ArkUI.ArkUI.Full
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
id | string | 是 | 目标组件的组件标识 |
options12+ | SnapshotOptions | 否 | 截图相关的自定义参数。 |
返回值:
类型 | 说明 |
---|---|
Promise<image.PixelMap> | 截图返回的结果。 |
错误码:
以下错误码的详细介绍。
错误码ID | 错误信息 |
---|---|
401 | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed. |
100001 | Invalid ID. |
示例:
说明
直接使用componentSnapshot可能导致实例不明确的问题,建议使用getUIContext获取UIContext实例,并使用getComponentSnapshot获取绑定实例的componentSnapshot。
import { componentSnapshot } from '@kit.ArkUI';
import { image } from '@kit.ImageKit';
@Entry
@Component
struct SnapshotExample {
@State pixmap: image.PixelMap | undefined = undefined
build() {
Column() {
Row() {
Image(this.pixmap).width(200).height(200).border({ color: Color.Black, width: 2 }).margin(5)
Image($r('app.media.img')).autoResize(true).width(200).height(200).margin(5).id("root")
}
Button("click to generate UI snapshot")
.onClick(() => {
// 建议使用this.getUIContext().getComponentSnapshot().get()
componentSnapshot.get("root", {scale : 2, waitUntilRenderFinished : true})
.then((pixmap: image.PixelMap) => {
this.pixmap = pixmap
}).catch((err:Error) => {
console.log("error: " + err)
})
}).margin(10)
}
.width('100%')
.height('100%')
.alignItems(HorizontalAlign.Center)
}
}
componentSnapshot.createFromBuilder
createFromBuilder(builder: CustomBuilder, callback: AsyncCallback<image.PixelMap>, delay?: number, checkImageStatus?: boolean, options?: SnapshotOptions): void
在应用后台渲染CustomBuilder自定义组件,并输出其截图。通过回调返回结果并支持在回调中获取离屏组件绘制区域坐标和大小。
说明
由于需要等待组件构建、渲染成功,离屏截图的回调有500ms以内的延迟。
builder中的组件不支持设置动画相关的属性,如transition。
部分执行耗时任务的组件可能无法及时在截图前加载完成,因此会截取不到加载成功后的图像。例如:加载网络图片的Image组件、Web组件。
元服务API: 从API version 12开始,该接口支持在元服务中使用。
系统能力: SystemCapability.ArkUI.ArkUI.Full
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
builder | CustomBuilder | 是 | 自定义组件构建函数。 说明: 不支持全局builder。 |
callback | AsyncCallback<image.PixelMap> | 是 | 截图返回结果的回调。支持在回调中获取离屏组件绘制区域坐标和大小。 |
delay12+ | number | 否 | 指定触发截图指令的延迟时间。当布局中使用了图片组件时,需要指定延迟时间,以便系统解码图片资源。资源越大,解码需要的时间越长,建议尽量使用不需要解码的PixelMap资源。 当使用PixelMap资源或对Image组件设置syncload为true时,可以配置delay为0,强制不等待触发截图。该延迟时间并非指接口从调用到返回的时间,由于系统需要对传入的builder进行临时离屏构建,因此返回的时间通常要比该延迟时间长。 说明: 截图接口传入的builder中,不应使用状态变量控制子组件的构建,如果必须要使用,在调用截图接口时,也不应再有变化,以避免出现截图不符合预期的情况。 默认值:300 单位:毫秒 |
checkImageStatus12+ | boolean | 否 | 指定是否允许在截图之前,校验图片解码状态。如果为true,则会在截图之前检查所有Image组件是否已经解码完成,如果没有完成检查,则会放弃截图并返回异常。 默认值:false |
options12+ | SnapshotOptions | 否 | 截图相关的自定义参数。 |
错误码:
以下错误码的详细介绍。
错误码ID | 错误信息 |
---|---|
401 | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed. |
100001 | The builder is not a valid build function. |
160001 | An image component in builder is not ready for taking a snapshot. The check for the ready state is required when the checkImageStatus option is enabled. |
示例:
说明
直接使用componentSnapshot可能导致实例不明确的问题,建议使用getUIContext获取UIContext实例,并使用getComponentSnapshot获取绑定实例的componentSnapshot。
import { componentSnapshot } from '@kit.ArkUI';
import { image } from '@kit.ImageKit';
@Entry
@Component
struct OffscreenSnapshotExample {
@State pixmap: image.PixelMap | undefined = undefined
@Builder
RandomBuilder() {
Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
Text('Test menu item 1')
.fontSize(20)
.width(100)
.height(50)
.textAlign(TextAlign.Center)
Divider().height(10)
Text('Test menu item 2')
.fontSize(20)
.width(100)
.height(50)
.textAlign(TextAlign.Center)
}
.width(100)
.id("builder")
}
build() {
Column() {
Button("click to generate offscreen UI snapshot")
.onClick(() => {
// 建议使用this.getUIContext().getComponentSnapshot().createFromBuilder()
componentSnapshot.createFromBuilder(()=>{this.RandomBuilder()},
(error: Error, pixmap: image.PixelMap) => {
if(error){
console.log("error: " + JSON.stringify(error))
return;
}
this.pixmap = pixmap
// save pixmap to file
// ....
// get component size and location
let info = this.getUIContext().getComponentUtils().getRectangleById("builder")
console.log(info.size.width + ' ' + info.size.height + ' ' + info.localOffset.x + ' ' + info.localOffset.y + ' ' + info.windowOffset.x + ' ' + info.windowOffset.y)
}, 320, true, {scale : 2, waitUntilRenderFinished : true})
})
Image(this.pixmap)
.margin(10)
.height(200)
.width(200)
.border({ color: Color.Black, width: 2 })
}.width('100%').margin({ left: 10, top: 5, bottom: 5 }).height(300)
}
}
componentSnapshot.createFromBuilder
createFromBuilder(builder: CustomBuilder, delay?: number, checkImageStatus?: boolean, options?: SnapshotOptions): Promise<image.PixelMap>
在应用后台渲染CustomBuilder自定义组件,并输出其截图。通过Promise返回结果并支持获取离屏组件绘制区域坐标和大小。
说明
由于需要等待组件构建、渲染成功,离屏截图的回调有500ms以内的延迟。
builder中的组件不支持设置动画相关的属性,如transition。
部分执行耗时任务的组件可能无法及时在截图前加载完成,因此会截取不到加载成功后的图像。例如:加载网络图片的Image组件、Web组件。
元服务API: 从API version 12开始,该接口支持在元服务中使用。
系统能力: SystemCapability.ArkUI.ArkUI.Full
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
builder | CustomBuilder | 是 | 自定义组件构建函数。 说明: 不支持全局builder。 |
delay12+ | number | 否 | 指定触发截图指令的延迟时间。当布局中使用了图片组件时,需要指定延迟时间,以便系统解码图片资源。资源越大,解码需要的时间越长,建议尽量使用不需要解码的PixelMap资源。 当使用PixelMap资源或对Image组件设置syncload为true时,可以配置delay为0,强制不等待触发截图。该延迟时间并非指接口从调用到返回的时间,由于系统需要对传入的builder进行临时离屏构建,因此返回的时间通常要比该延迟时间长。 说明: 截图接口传入的builder中,不应使用状态变量控制子组件的构建,如果必须要使用,在调用截图接口时,也不应再有变化,以避免出现截图不符合预期的情况。 默认值:300 单位:毫秒 |
checkImageStatus12+ | boolean | 否 | 指定是否允许在截图之前,校验图片解码状态。如果为true,则会在截图之前检查所有Image组件是否已经解码完成,如果没有完成检查,则会放弃截图并返回异常。 默认值:false |
options12+ | SnapshotOptions | 否 | 截图相关的自定义参数。 |
返回值:
类型 | 说明 |
---|---|
Promise<image.PixelMap> | 截图返回的结果。 |
错误码:
以下错误码的详细介绍。
错误码ID | 错误信息 |
---|---|
401 | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed. |
100001 | The builder is not a valid build function. |
160001 | An image component in builder is not ready for taking a snapshot. The check for the ready state is required when the checkImageStatus option is enabled. |
示例:
说明
直接使用componentSnapshot可能导致实例不明确的问题,建议使用getUIContext获取UIContext实例,并使用getComponentSnapshot获取绑定实例的componentSnapshot。
import { componentSnapshot } from '@kit.ArkUI'
import { image } from '@kit.ImageKit'
@Entry
@Component
struct OffscreenSnapshotExample {
@State pixmap: image.PixelMap | undefined = undefined
@Builder
RandomBuilder() {
Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
Text('Test menu item 1')
.fontSize(20)
.width(100)
.height(50)
.textAlign(TextAlign.Center)
Divider().height(10)
Text('Test menu item 2')
.fontSize(20)
.width(100)
.height(50)
.textAlign(TextAlign.Center)
}
.width(100)
.id("builder")
}
build() {
Column() {
Button("click to generate offscreen UI snapshot")
.onClick(() => {
// 建议使用this.getUIContext().getComponentSnapshot().createFromBuilder()
componentSnapshot.createFromBuilder(()=>{this.RandomBuilder()}, 320, true, {scale : 2, waitUntilRenderFinished : true})
.then((pixmap: image.PixelMap) => {
this.pixmap = pixmap
// save pixmap to file
// ....
// get component size and location
let info = this.getUIContext().getComponentUtils().getRectangleById("builder")
console.log(info.size.width + ' ' + info.size.height + ' ' + info.localOffset.x + ' ' + info.localOffset.y + ' ' + info.windowOffset.x + ' ' + info.windowOffset.y)
}).catch((err:Error) => {
console.log("error: " + err)
})
})
Image(this.pixmap)
.margin(10)
.height(200)
.width(200)
.border({ color: Color.Black, width: 2 })
}.width('100%').margin({ left: 10, top: 5, bottom: 5 }).height(300)
}
}
componentSnapshot.getSync12+
getSync(id: string, options?: SnapshotOptions): image.PixelMap
获取已加载的组件的截图,传入组件的组件标识,找到对应组件进行截图。同步等待截图完成返回PixelMap。
说明
截图会获取最近一帧的绘制内容。如果在组件触发更新的同时调用截图,更新的渲染内容不会被截取到,截图会返回上一帧的绘制内容。
元服务API: 从API version 12开始,该接口支持在元服务中使用。
系统能力: SystemCapability.ArkUI.ArkUI.Full
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
id | string | 是 | 目标组件的组件标识 |
options | SnapshotOptions | 否 | 截图相关的自定义参数。 |
返回值:
类型 | 说明 |
---|---|
image.PixelMap | 截图返回的结果。 |
错误码:
以下错误码的详细介绍。
错误码ID | 错误信息 |
---|---|
401 | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed. |
100001 | Invalid ID. |
160002 | Timeout. |
示例:
说明
直接使用componentSnapshot可能导致实例不明确的问题,建议使用getUIContext获取UIContext实例,并使用getComponentSnapshot获取绑定实例的componentSnapshot。
import { componentSnapshot } from '@kit.ArkUI';
import { image } from '@kit.ImageKit';
@Entry
@Component
struct SnapshotExample {
@State pixmap: image.PixelMap | undefined = undefined
build() {
Column() {
Row() {
Image(this.pixmap).width(200).height(200).border({ color: Color.Black, width: 2 }).margin(5)
Image($r('app.media.img')).autoResize(true).width(200).height(200).margin(5).id("root")
}
Button("click to generate UI snapshot")
.onClick(() => {
try {
// 建议使用this.getUIContext().getComponentSnapshot().getSync()
let pixelmap = componentSnapshot.getSync("root", {scale : 2, waitUntilRenderFinished : true})
this.pixmap = pixelmap
} catch (error) {
console.error("getSync errorCode: " + error.code + " message: " + error.message)
}
}).margin(10)
}
.width('100%')
.height('100%')
.alignItems(HorizontalAlign.Center)
}
}
SnapshotOptions12+
系统能力: SystemCapability.ArkUI.ArkUI.Full
元服务API: 从API version 12开始,该接口支持在元服务中使用。
名称 | 类型 | 必填 | 说明 |
---|---|---|---|
scale | number | 否 | 指定截图时图形侧绘制pixelmap的缩放比例,比例过大时截图时间会变长,或者截图可能会失败。 默认值:1 说明: 请不要截取过大尺寸的图片,截图不建议超过屏幕尺寸的大小。当要截取的图片目标长宽超过底层限制时,截图会返回失败,不同设备的底层限制不同。 |
waitUntilRenderFinished | boolean | 否 | 指定是否强制等待系统执行截图指令前所有绘制指令都执行完成之后再截图。该选项可尽可能确保截图内容是最新的状态,应尽量开启,要注意的是,开启后接口可能需要更长的时间返回,具体的时间依赖页面当时时刻需要重绘区域的多少。 默认值:false |