当前位置: 首页 > news >正文

鸿蒙NEXT开发组件截图和窗口截图工具类SnapshotUtil(ArkTs)

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();}
}

相关文章:

  • 榕壹云信用租赁系统:基于ThinkPHP+MySQL+UniApp的全链路免押租赁解决方案
  • 声纹监测技术在新能源汽车的应用场景解析
  • FPGA-数字时钟
  • 深入浅出限流算法(一):简单但有“坑”的固定窗口计数器
  • ORM、Hibernate 与 MyBatis 详解:选择合适的框架
  • 2025年渗透测试面试题总结-拷打题库24(题目+回答)
  • Ethan独立开发产品日报 | 2025-04-27
  • 系统架构-DSSAABSD
  • Django 缓存框架
  • 华为云空间安卓版存储扩展与文件管理体验测评
  • AI大模型学习十四、白嫖腾讯Cloud Studio AI环境 通过Ollama+Dify+DeepSeek构建生成式 AI 应用-接入DeepSeek大模型
  • 使用 ELK 实现全链路追踪:从零到一的实践指南
  • 阿里云服务器(ECS)基础指南:从入门到核心场景解析​
  • ubuntu新增磁盘挂载
  • Jackson 使用方法详解
  • 操作系统八股问——连载ing
  • 具身智能机器人的应用场景及最新进展
  • 解决MacOS端口被占用问题
  • 安卓基础(接口interface)
  • 高压场景首选:CKESC ROCK 120A-H CAN 电调技术解析与实测报告
  • 事关稳就业稳经济,10张海报看懂这场发布会的政策信号
  • “富卫保险冠军赛马日”创双纪录,打造赛马旅游盛宴,印证香港联通国际优势
  • 哈马斯官员:只要以军持续占领,哈马斯就不会放下武器
  • “梅花奖”快闪走入上海张园,朱洁静在石库门前起舞
  • 拉卡拉一季度净利约1亿降超五成,去年净利3.5亿降逾23%
  • 四川公布一起影视盗版案例:1个网站2人团伙盗售30多万部