import { image } from '@kit.ImageKit';
import { componentSnapshot, window } from '@kit.ArkUI';
import { AppUtil } from './AppUtil';
import { ArrayUtil } from './ArrayUtil';
/**
* 组件截图和窗口截图工具类
* @author 鸿蒙布道师
* @since 2025/04/28
*/
export class SnapshotUtil {
private static callbacks: VoidCallback[] = []; // 缓存的截图回调列表。
private static snapshotCallback: VoidCallback | undefined; // 全局的截图监听回调。
/**
* 获取已加载组件的截图(异步方式)。
* @param id 目标组件的唯一标识。
* @param options 截图相关的自定义参数。
* @returns 返回 Promise<image.PixelMap> 截图结果。
*/
static async get(id: string, options?: componentSnapshot.SnapshotOptions): Promise<image.PixelMap> {
if (!id) {
throw new Error('Component ID cannot be empty.');
}
return componentSnapshot.get(id, options);
}
/**
* 获取已加载组件的截图(同步方式)。
* @param id 目标组件的唯一标识。
* @param options 截图相关的自定义参数。
* @returns 返回 Promise<image.PixelMap> 截图结果。
*/
static getSync(id: string, options?: componentSnapshot.SnapshotOptions): Promise<image.PixelMap> {
if (!id) {
throw new Error('Component ID cannot be empty.');
}
return componentSnapshot.get(id, options);
}
/**
* 渲染 CustomBuilder 自定义组件并获取其截图。
* @param builder 自定义组件构建函数。
* @param delay 触发截图指令的延迟时间(默认值:300 毫秒)。
* @param checkImageStatus 是否校验图片解码状态(默认值:false)。
* @param options 截图相关的自定义参数。
* @returns 返回 Promise<image.PixelMap> 截图结果。
*/
static createFromBuilder(
builder: CustomBuilder,
delay: number = 300,
checkImageStatus: boolean = false,
options?: componentSnapshot.SnapshotOptions
): Promise<image.PixelMap> {
if (!builder) {
throw new Error('CustomBuilder cannot be undefined.');
}
return componentSnapshot.createFromBuilder(builder, delay, checkImageStatus, options);
}
/**
* 获取窗口截图(异步方式)。
* @param windowClass 窗口实例(默认为主窗口)。
* @returns 返回 Promise<image.PixelMap> 截图结果。
*/
static async snapshot(windowClass?: window.Window): Promise<image.PixelMap> {
const targetWindow = windowClass ?? AppUtil.getMainWindow();
if (!targetWindow) {
throw new Error('Target window is not available.');
}
return targetWindow.snapshot();
}
/**
* 开启系统截屏事件的监听。
* @param callback 截图回调函数。
*/
static onSnapshotListener(callback: VoidCallback): void {
if (!callback) {
throw new Error('Callback function cannot be undefined.');
}
if (!ArrayUtil.contains(SnapshotUtil.callbacks, callback)) {
SnapshotUtil.callbacks.push(callback);
}
if (!SnapshotUtil.snapshotCallback) {
SnapshotUtil.snapshotCallback = () => {
SnapshotUtil.callbacks.forEach((cb) => cb?.());
};
AppUtil.getMainWindow()?.on('screenshot', SnapshotUtil.snapshotCallback);
}
}
/**
* 关闭系统截屏事件的监听。
* @param callback 要移除的监听回调(如果为空,则移除所有监听)。
*/
static removeSnapshotListener(callback?: VoidCallback): void {
if (callback) {
ArrayUtil.remove(SnapshotUtil.callbacks, callback);
} else {
SnapshotUtil.callbacks = [];
}
if (SnapshotUtil.callbacks.length === 0) {
const mainWindow = AppUtil.getMainWindow();
if (mainWindow) {
if (SnapshotUtil.snapshotCallback) {
mainWindow.off('screenshot', SnapshotUtil.snapshotCallback);
} else {
mainWindow.off('screenshot');
}
SnapshotUtil.snapshotCallback = undefined;
}
}
}
/**
* 检查窗口是否可用。
* @param windowClass 窗口实例。
* @returns 如果窗口可用返回 true,否则返回 false。
*/
private static isWindowAvailable(windowClass?: window.Window): boolean {
return !!windowClass || !!AppUtil.getMainWindow();
}
}
代码如下:
import { image } from '@kit.ImageKit';
import { componentSnapshot, window } from '@kit.ArkUI';
import { AppUtil } from './AppUtil';
import { ArrayUtil } from './ArrayUtil';
/**
* 组件截图和窗口截图工具类
* @author 鸿蒙布道师
* @since 2025/04/28
*/
export class SnapshotUtil {
private static callbacks: VoidCallback[] = []; // 缓存的截图回调列表。
private static snapshotCallback: VoidCallback | undefined; // 全局的截图监听回调。
/**
* 获取已加载组件的截图(异步方式)。
* @param id 目标组件的唯一标识。
* @param options 截图相关的自定义参数。
* @returns 返回 Promise<image.PixelMap> 截图结果。
*/
static async get(id: string, options?: componentSnapshot.SnapshotOptions): Promise<image.PixelMap> {
if (!id) {
throw new Error('Component ID cannot be empty.');
}
return componentSnapshot.get(id, options);
}
/**
* 获取已加载组件的截图(同步方式)。
* @param id 目标组件的唯一标识。
* @param options 截图相关的自定义参数。
* @returns 返回 Promise<image.PixelMap> 截图结果。
*/
static getSync(id: string, options?: componentSnapshot.SnapshotOptions): Promise<image.PixelMap> {
if (!id) {
throw new Error('Component ID cannot be empty.');
}
return componentSnapshot.get(id, options);
}
/**
* 渲染 CustomBuilder 自定义组件并获取其截图。
* @param builder 自定义组件构建函数。
* @param delay 触发截图指令的延迟时间(默认值:300 毫秒)。
* @param checkImageStatus 是否校验图片解码状态(默认值:false)。
* @param options 截图相关的自定义参数。
* @returns 返回 Promise<image.PixelMap> 截图结果。
*/
static createFromBuilder(
builder: CustomBuilder,
delay: number = 300,
checkImageStatus: boolean = false,
options?: componentSnapshot.SnapshotOptions
): Promise<image.PixelMap> {
if (!builder) {
throw new Error('CustomBuilder cannot be undefined.');
}
return componentSnapshot.createFromBuilder(builder, delay, checkImageStatus, options);
}
/**
* 获取窗口截图(异步方式)。
* @param windowClass 窗口实例(默认为主窗口)。
* @returns 返回 Promise<image.PixelMap> 截图结果。
*/
static async snapshot(windowClass?: window.Window): Promise<image.PixelMap> {
const targetWindow = windowClass ?? AppUtil.getMainWindow();
if (!targetWindow) {
throw new Error('Target window is not available.');
}
return targetWindow.snapshot();
}
/**
* 开启系统截屏事件的监听。
* @param callback 截图回调函数。
*/
static onSnapshotListener(callback: VoidCallback): void {
if (!callback) {
throw new Error('Callback function cannot be undefined.');
}
if (!ArrayUtil.contains(SnapshotUtil.callbacks, callback)) {
SnapshotUtil.callbacks.push(callback);
}
if (!SnapshotUtil.snapshotCallback) {
SnapshotUtil.snapshotCallback = () => {
SnapshotUtil.callbacks.forEach((cb) => cb?.());
};
AppUtil.getMainWindow()?.on('screenshot', SnapshotUtil.snapshotCallback);
}
}
/**
* 关闭系统截屏事件的监听。
* @param callback 要移除的监听回调(如果为空,则移除所有监听)。
*/
static removeSnapshotListener(callback?: VoidCallback): void {
if (callback) {
ArrayUtil.remove(SnapshotUtil.callbacks, callback);
} else {
SnapshotUtil.callbacks = [];
}
if (SnapshotUtil.callbacks.length === 0) {
const mainWindow = AppUtil.getMainWindow();
if (mainWindow) {
if (SnapshotUtil.snapshotCallback) {
mainWindow.off('screenshot', SnapshotUtil.snapshotCallback);
} else {
mainWindow.off('screenshot');
}
SnapshotUtil.snapshotCallback = undefined;
}
}
}
/**
* 检查窗口是否可用。
* @param windowClass 窗口实例。
* @returns 如果窗口可用返回 true,否则返回 false。
*/
private static isWindowAvailable(windowClass?: window.Window): boolean {
return !!windowClass || !!AppUtil.getMainWindow();
}
}