鸿蒙6.1 arkui.componentSnapshot组件截图坑:返回PixelMap不是dataURL
本文是「鸿蒙 6.1 API 23 开发坑系列」第 2 篇(ArkUI 桶第 2 篇)。本篇讲
@ohos.arkui.componentSnapshotnamespace(API 10+,鸿蒙 6.1 API 23 基座)——组件截图三个方法get/getSync/createFromBuilder。鸿蒙坑根因:①import坑——import { componentSnapshot } from编译错(has no exported member),必须import componentSnapshot from(default import);② 返回值坑——get(id)返回Promise<image.PixelMap>不是dataURL字符串(React html2canvas 返回 dataURL),image.PixelMap是像素图有getImageInfo/getPixelBytes可读像素;③createFromBuilder(builder)的 builder 参数是CustomBuilder(@Builder装饰的函数)不是 Component。
一、开篇:鸿蒙 componentSnapshot 不是 html2canvas,是「返回 PixelMap 像素图」
你写 React 时,组件截图用 html2canvas(返回 canvas → toDataURL 转 dataURL 字符串):
// React html2canvas:返回 canvas → toDataURL 转 dataURL 字符串
async function snapshotComponent() {
// ❌ html2canvas 返回 HTMLCanvasElement,toDataURL() 转 dataURL 字符串
const canvas: HTMLCanvasElement = await html2canvas(document.getElementById('target'))
const dataURL: string = canvas.toDataURL('image/jpeg', 0.9) // ❌ dataURL 字符串
// ❌ React html2canvas:返回 canvas → dataURL 字符串,不是 PixelMap 像素图
}
你写鸿蒙 ArkTS 时,组件截图用 componentSnapshot.get(id)(返回 Promise<image.PixelMap> 像素图):
// ArkTS componentSnapshot:返回 Promise<image.PixelMap> 像素图,不是 dataURL 字符串
import componentSnapshot from '@ohos.arkui.componentSnapshot' // ✅ default import
import image from '@ohos.multimedia.image'
async function snapshotComponent() {
// ✅ get(id) 返回 Promise<image.PixelMap>,image.PixelMap 是像素图不是 dataURL
const pixelMap: image.PixelMap = await componentSnapshot.get('snapshotTarget')
const imageInfo: image.ImageInfo = await pixelMap.getImageInfo()
// ✅ PixelMap 有 getImageInfo/getPixelBytes 可读像素,不是 dataURL 字符串
const width: number = imageInfo.size.width
const height: number = imageInfo.size.height
}
React html2canvas vs 鸿蒙 componentSnapshot 的区别:React 把组件截图当 canvas 转 dataURL(html2canvas 返回 HTMLCanvasElement + toDataURL() 转 dataURL 字符串,base64 编码字符串),ArkTS 把组件截图当 PixelMap 像素图(componentSnapshot.get 返回 Promise<image.PixelMap>,image.PixelMap 是像素图有 getImageInfo/getPixelBytes 可读像素,不是 dataURL 字符串)。根因不是 dataURL 字符串是 PixelMap 像素图——鸿蒙返回 image.PixelMap 像素图,有 getImageInfo/getPixelBytes 可读像素。
二、根因:鸿蒙 componentSnapshot 的三个绑定机制
鸿蒙 @ohos.arkui.componentSnapshot namespace(API 10+)有三个截图方法,每个返回 image.PixelMap 像素图。绑定机制来自三重根因。
机制 1:import 坑——default import 不是 named import
鸿蒙坑根因:import { componentSnapshot } from 编译错——必须 import componentSnapshot from:
// ❌ 鸿蒙坑:import { componentSnapshot } from 编译错(has no exported member)
// ❌ 编译错:Module '"@ohos.arkui.componentSnapshot"' has no exported member 'componentSnapshot'
// ❌ 错误信息:Did you mean to use 'import componentSnapshot from "@ohos.arkui.componentSnapshot"' instead?
import { componentSnapshot } from '@ohos.arkui.componentSnapshot' // ❌ named import 编译错
// ✅ 正确用法:default import(componentSnapshot 是 default export 不是 named export)
import componentSnapshot from '@ohos.arkui.componentSnapshot' // ✅ default import
// 鸿蒙坑根因:componentSnapshot 是 default export,必须 default import 不是 named import
import 坑根因:@ohos.arkui.componentSnapshot 的 componentSnapshot 是 declare namespace(default namespace export),不是 named export,所以 import { componentSnapshot } 触发 has no exported member 'componentSnapshot' 编译错。正确用法是 import componentSnapshot from(default import)。
机制 2:get 返回 Promise<image.PixelMap> 不是 dataURL 字符串
鸿蒙坑根因:get(id) 返回 Promise<image.PixelMap> 像素图,不是 dataURL 字符串:
// ✅ get(id): Promise<image.PixelMap> 异步截图(返回 Promise<image.PixelMap>,不是 dataURL)
import componentSnapshot from '@ohos.arkui.componentSnapshot'
import image from '@ohos.multimedia.image'
async function asyncSnapshot() {
// ✅ get(id) 返回 Promise<image.PixelMap>,image.PixelMap 是像素图不是 dataURL
const pixelMap: image.PixelMap = await componentSnapshot.get('snapshotTarget')
// ✅ PixelMap 有 getImageInfo/getPixelBytes 可读像素
const imageInfo: image.ImageInfo = await pixelMap.getImageInfo()
const width: number = imageInfo.size.width
const height: number = imageInfo.size.height
// 鸿蒙坑根因:get 返回 Promise<image.PixelMap> 像素图,React html2canvas 返回 dataURL 字符串
}
// ✅ getSync(id): image.PixelMap 同步截图(API 12+,直接返回不用 await)
function syncSnapshot() {
// ✅ getSync 是 API 12+ 同步方法,直接返回 image.PixelMap 不用 await
const pixelMap: image.PixelMap = componentSnapshot.getSync('snapshotTarget')
// 鸿蒙坑:getSync 是 API 12+ 同步方法,不是 Promise 不用 await
}
get vs getSync 的区别:get(id): Promise<image.PixelMap> 异步截图(API 10+,返回 Promise 需要 await),getSync(id): image.PixelMap 同步截图(API 12+,直接返回 image.PixelMap 不用 await,不是 Promise)。鸿蒙坑:getSync 是 API 12+ 同步方法,不是 Promise 不用 await,直接返回 image.PixelMap。
image.PixelMap vs dataURL 的区别:image.PixelMap 是鸿蒙像素图接口(有 getImageInfo/getPixelBytes 可读像素,release 释放资源),dataURL 是 base64 编码字符串(React html2canvas 返回,无 getImageInfo/getPixelBytes)。根因不是 dataURL 字符串是 PixelMap 像素图——鸿蒙返回 image.PixelMap 像素图,有 getImageInfo/getPixelBytes 可读像素。
机制 3:createFromBuilder(builder) 的 builder 参数是 CustomBuilder 不是 Component
鸿蒙坑根因:createFromBuilder(builder) 的 builder 参数是 CustomBuilder(@Builder 装饰的函数),不是 Component:
// ✅ createFromBuilder(builder) 从 CustomBuilder 截图(builder 参数是 @Builder 函数不是 Component)
import componentSnapshot from '@ohos.arkui.componentSnapshot'
// ✅ @Builder 装饰的函数是 CustomBuilder 类型(createFromBuilder 的 builder 参数)
@Builder
function MySnapshotBuilder() {
Column({ space: 4 }) {
Text('CustomBuilder 截图内容').fontSize(14).fontColor('#28a745')
}
.padding(12).backgroundColor('#d4edda').borderRadius(8)
}
async function builderSnapshot() {
// ✅ createFromBuilder(builder) 返回 Promise<image.PixelMap>
// ✅ 鸿蒙坑:builder 参数是 CustomBuilder(@Builder 函数),不是 Component
const pixelMap: image.PixelMap = await componentSnapshot.createFromBuilder(MySnapshotBuilder)
// 鸿蒙坑根因:builder 参数是 CustomBuilder(@Builder 装饰的函数),不是 Component
}
createFromBuilder 的 builder 参数坑:createFromBuilder(builder: CustomBuilder, ...) 的 builder 参数是 CustomBuilder 类型(@Builder 装饰的函数引用,不是 Component 实例,不是 build() 返回值)。鸿蒙坑:传 Component 实例或 build() 返回值会类型错——必须传 @Builder 装饰的函数引用(MySnapshotBuilder 不是 MySnapshotBuilder())。
三、真机配图:鸿蒙 arkui.componentSnapshot 组件截图坑——get/getSync/createFromBuilder

真机配图展示鸿蒙 arkui.componentSnapshot 组件截图坑:
- 初始态:鸿蒙 6.1 arkui.componentSnapshot 组件截图坑标题,截图目标组件(红框 id=snapshotTarget,四角文字左上/右上/左下/右下),场景1~4 卡片(get/getSync/createFromBuilder/截图存文件),要点说明
- get(id) 异步截图态:点击「① get(id) 异步截图」按钮,snapshotStatus 显示「✅ componentSnapshot.get(id) 异步截图成功:PixelMap 1066x278」,截图次数 1——get 返回 Promise<image.PixelMap> 验证
- getSync(id) 同步截图态:点击「② getSync(id) 同步截图」按钮,syncSnapshotStatus 显示「✅ componentSnapshot.getSync(id) 同步截图成功:返回 image.PixelMap(不用 await)」,截图次数 2——getSync 同步返回 image.PixelMap 验证
- createFromBuilder 态:点击「③ createFromBuilder 截图」按钮,builderSnapshotStatus 显示「✅ createFromBuilder(builder) 截图成功:PixelMap 393x78」,截图次数 3——createFromBuilder 从 CustomBuilder 截图验证
- 截图存文件态:点击「⑦ 截图存文件」按钮,savedFilePath 显示「/data/storage/…/cache/snapshot_*.jpeg」,截图次数 4——PixelMap 存文件验证(image.createImagePacker + fs.writeSync)
四、真解法:鸿蒙 componentSnapshot 的三个场景
场景 1:get(id) 异步截图 + getSync(id) 同步截图——90% 场景首选
get/getSync 截图用 componentSnapshot.get('id') + componentSnapshot.getSync('id'):
// ✅ 场景 1:get(id) 异步截图 + getSync(id) 同步截图(API 10/12,90% 场景首选)
import componentSnapshot from '@ohos.arkui.componentSnapshot' // ✅ default import
import image from '@ohos.multimedia.image'
// ✅ get(id): Promise<image.PixelMap> 异步截图(API 10+,返回 Promise 需要 await)
async function asyncSnapshot() {
const pixelMap: image.PixelMap = await componentSnapshot.get('snapshotTarget')
const imageInfo: image.ImageInfo = await pixelMap.getImageInfo()
// PixelMap 像素图:getImageInfo 读尺寸,getPixelBytes 读像素
}
// ✅ getSync(id): image.PixelMap 同步截图(API 12+,直接返回不用 await)
function syncSnapshot() {
const pixelMap: image.PixelMap = componentSnapshot.getSync('snapshotTarget')
// getSync 同步返回 image.PixelMap,不是 Promise 不用 await
}
// get/getSync 截图:90% 场景首选,返回 image.PixelMap 像素图不是 dataURL
鸿蒙 componentSnapshot API 真名坑:import componentSnapshot from '@ohos.arkui.componentSnapshot'(default import 不是 named import);get(id: string, callback?: AsyncCallback<image.PixelMap>, options?: SnapshotOptions): void 异步截图(API 10+,callback 可选);get(id: string, options?: SnapshotOptions): Promise<image.PixelMap> Promise 异步截图(API 10+,返回 Promise<image.PixelMap>);getSync(id: string, options?: SnapshotOptions): image.PixelMap 同步截图(API 12+,直接返回 image.PixelMap);image.PixelMap 像素图接口(getImageInfo/getPixelBytes/release);SysCap SystemCapability.ArkUI.ArkUI.Full;@crossplatform 跨平台;@atomicservice 原子化服务;SnapshotOptions(API 15+,SnapshotRegion/left/right/top/bottom 矩形区域截图)。
场景 2:createFromBuilder(builder) 从 CustomBuilder 截图
createFromBuilder 截图用 componentSnapshot.createFromBuilder(MyBuilder) + @Builder 装饰函数:
// ✅ 场景 2:createFromBuilder(builder) 从 CustomBuilder 截图(API 10)
import componentSnapshot from '@ohos.arkui.componentSnapshot'
// ✅ @Builder 装饰的函数是 CustomBuilder 类型(createFromBuilder 的 builder 参数)
@Builder
function MySnapshotBuilder() {
Column({ space: 4 }) {
Text('CustomBuilder 截图内容').fontSize(14).fontColor('#28a745').fontWeight(FontWeight.Bold)
Text('createFromBuilder 从 Builder 截图').fontSize(10).fontColor('#888')
}
.padding(12).backgroundColor('#d4edda').borderRadius(8)
}
async function builderSnapshot() {
// ✅ createFromBuilder(builder) 返回 Promise<image.PixelMap>
// ✅ 鸿蒙坑:builder 参数是 CustomBuilder(@Builder 函数引用),不是 Component 实例
const pixelMap: image.PixelMap = await componentSnapshot.createFromBuilder(MySnapshotBuilder)
// ✅ createFromBuilder 也有 callback 和 delay/checkImageStatus/options 参数
// componentSnapshot.createFromBuilder(MyBuilder, 500, true, options) // delay=500ms, checkImageStatus=true
}
// createFromBuilder 从 CustomBuilder 截图:builder 参数是 @Builder 函数引用不是 Component
鸿蒙 createFromBuilder API 真名坑:createFromBuilder(builder: CustomBuilder, callback?: AsyncCallback<image.PixelMap>, delay?: number, checkImageStatus?: boolean, options?: SnapshotOptions): void callback 异步(API 10+);createFromBuilder(builder: CustomBuilder, delay?: number, checkImageStatus?: boolean, options?: SnapshotOptions): Promise<image.PixelMap> Promise 异步(API 10+);CustomBuilder 是 @Builder 装饰的函数类型(传函数引用 MyBuilder 不是调用 MyBuilder());delay 延迟截图毫秒数(等组件渲染完);checkImageStatus 检查图片状态(true 等图片加载完再截图);鸿蒙坑:builder 参数传 Component 实例或 build() 返回值会类型错——必须传 @Builder 装饰的函数引用。
场景 3:PixelMap 存文件——image.createImagePacker + fs.writeSync
PixelMap 存文件用 image.createImagePacker().packing() 打包 JPEG buffer + fs.writeSync 写文件:
// ✅ 场景 3:PixelMap 存文件——image.createImagePacker + fs.writeSync(API 10)
import componentSnapshot from '@ohos.arkui.componentSnapshot'
import image from '@ohos.multimedia.image'
import fs from '@ohos.file.fs'
async function snapshotAndSave() {
// ✅ get(id) 截图返回 PixelMap
const pixelMap: image.PixelMap = await componentSnapshot.get('snapshotTarget')
// ✅ image.createImagePacker() 打包 PixelMap 为 JPEG buffer
const imagePacker: image.ImagePacker = image.createImagePacker()
const jpegBuffer: ArrayBuffer = await imagePacker.packing(pixelMap, {
format: 'image/jpeg', // ✅ format: 'image/jpeg' 不是 'jpeg'
quality: 90 // ✅ quality: 0-100
})
imagePacker.release() // ✅ release 释放 ImagePacker
// ✅ fs.openSync 打开文件 + fs.writeSync 写 buffer + fs.closeSync 关文件
const context = getContext(this) // ✅ getContext 获取 Context(@deprecated 警告但仍可用)
const cacheDir: string = context.cacheDir // ✅ cacheDir 缓存目录
const filePath: string = cacheDir + '/snapshot_' + Date.now() + '.jpeg'
const fileFd: number = fs.openSync(filePath, fs.OpenMode.CREATE | fs.OpenMode.WRITE_ONLY).fd // ✅ .fd 取文件描述符
fs.writeSync(fileFd, jpegBuffer) // ✅ writeSync(fd, buffer) 第一参传 fd
fs.closeSync(fileFd) // ✅ closeSync(fd) 关文件
}
// PixelMap 存文件:image.createImagePacker().packing JPEG buffer + fs.writeSync(fd, buffer)
鸿蒙 PixelMap 存文件 API 真名坑:image.createImagePacker(): image.ImagePacker 创建打包器(API 10+);imagePacker.packing(pixelMap, options?: image.PackingOption): Promise<ArrayBuffer> 打包 PixelMap 为 buffer(API 10+);PackingOption { format: 'image/jpeg', quality: 90 }(format 是 'image/jpeg' 不是 'jpeg',quality 0-100);imagePacker.release() 释放打包器;fs.openSync(path, mode): fs.File 同步打开文件(API 10+,.fd 取文件描述符);fs.writeSync(fd: number, buffer: ArrayBuffer) 同步写 buffer(API 10+,第一参传 fd 文件描述符,不是 File 实例);fs.closeSync(fd: number) 同步关文件;鸿蒙坑:fs.writeSync 第一参传 file.fd 文件描述符(不是 File 实例方法,是 namespace 顶层函数);getContext(this) 已 @deprecated 警告但仍可用(推荐用 this.getContext() 或组件 Context)。
五、一句话哲学
写鸿蒙 ArkUI 记住:componentSnapshot 不是 html2canvas 是「返回 image.PixelMap 像素图」——鸿蒙 6.1 API 23
@ohos.arkui.componentSnapshotnamespace(API 10+,鸿蒙 6.1 API 23 基座,SysCap SystemCapability.ArkUI.ArkUI.Full,@crossplatform @atomicservice)。根因不是 dataURL 字符串是 PixelMap 像素图——import componentSnapshot from(✅ default import,❌import { componentSnapshot } from编译错has no exported member),get(id): Promise<image.PixelMap>异步截图(API 10+,返回 Promise<image.PixelMap> 像素图不是 dataURL 字符串,image.PixelMap 有 getImageInfo/getPixelBytes/release 可读像素),getSync(id): image.PixelMap同步截图(API 12+,直接返回 image.PixelMap 不用 await 不是 Promise),createFromBuilder(builder: CustomBuilder): Promise<image.PixelMap>从 CustomBuilder 截图(builder 参数是@Builder装饰的函数引用不是 Component 实例,有 delay/checkImageStatus/options 参数),image.createImagePacker().packing(pixelMap, { format: 'image/jpeg', quality: 90 })打包 PixelMap 为 JPEG buffer(format 是'image/jpeg'不是'jpeg'),fs.writeSync(fd, buffer)写文件(第一参传file.fd文件描述符,是 namespace 顶层函数不是 File 实例方法)。componentSnapshot 返回 image.PixelMap 像素图不是 dataURL 字符串是鸿蒙 6.1 arkui.componentSnapshot 组件截图坑核心!
能力系列回链
- 鸿蒙 7.0 新特性篇 1~17(沉浸式毛玻璃/Component3D/智能体框架/方舟引擎/星盾安全/星河互联/空间音频/可变字体/游戏快启/分布式数据盾/LTPO 可变帧率/AI 文档识别/多形态服务窗口/AI 反诈/机密计算/空间计算/小艺全面进化)
- 鸿蒙 6.1 API 23 开发坑系列篇 1「ArkUI.modifier 装饰器坑」——attributeModifier + AttributeModifier 状态化节点修改器
- 鸿蒙 6.1 API 23 开发坑系列篇 2「arkui.componentSnapshot 组件截图坑」——get/getSync/createFromBuilder 返回 image.PixelMap(本文)
真机 demo 完整代码
// 鸿蒙 6.1 API 23 开发坑系列篇 2:arkui.componentSnapshot 组件截图坑——get/getSync/createFromBuilder 返回 image.PixelMap 根因
import componentSnapshot from '@ohos.arkui.componentSnapshot'
import image from '@ohos.multimedia.image'
import fs from '@ohos.file.fs'
@Builder
function MySnapshotBuilder() {
Column({ space: 4 }) {
Text('CustomBuilder 截图内容').fontSize(14).fontColor('#28a745').fontWeight(FontWeight.Bold)
Text('createFromBuilder 从 Builder 截图').fontSize(10).fontColor('#888')
}
.padding(12)
.backgroundColor('#d4edda')
.borderRadius(8)
}
@Entry
@Component
struct Index {
@State log: string = '(未操作)'
@State snapshotStatus: string = '(未截)'
@State syncSnapshotStatus: string = '(未截)'
@State builderSnapshotStatus: string = '(未截)'
@State pixelMapWidth: number = 0
@State pixelMapHeight: number = 0
@State snapshotCount: number = 0
@State savedFilePath: string = '(未存)'
@State lastError: string = '(无错)'
aboutToAppear() {
this.log = '鸿蒙 6.1 arkui.componentSnapshot 组件截图坑:get/getSync/createFromBuilder 返回 image.PixelMap'
}
async demonstrateAsyncSnapshot() {
try {
const pixelMap: image.PixelMap = await componentSnapshot.get('snapshotTarget')
const imageInfo: image.ImageInfo = await pixelMap.getImageInfo()
this.pixelMapWidth = imageInfo.size.width
this.pixelMapHeight = imageInfo.size.height
this.snapshotStatus = '✅ componentSnapshot.get(id) 异步截图成功:PixelMap ' + this.pixelMapWidth + 'x' + this.pixelMapHeight
this.log = '✅ get(id) 返回 Promise<image.PixelMap>(不是 dataURL),PixelMap 像素图 ' + this.pixelMapWidth + 'x' + this.pixelMapHeight
this.snapshotCount++
this.lastError = '(无错)'
} catch (e) {
this.lastError = '❌ get 异步截图错:' + e.message
}
}
demonstrateSyncSnapshot() {
try {
const pixelMap: image.PixelMap = componentSnapshot.getSync('snapshotTarget')
this.syncSnapshotStatus = '✅ componentSnapshot.getSync(id) 同步截图成功:返回 image.PixelMap(不用 await)'
this.snapshotCount++
this.lastError = '(无错)'
} catch (e) {
this.lastError = '❌ getSync 同步截图错:' + e.message
}
}
async demonstrateBuilderSnapshot() {
try {
const pixelMap: image.PixelMap = await componentSnapshot.createFromBuilder(MySnapshotBuilder)
const imageInfo: image.ImageInfo = await pixelMap.getImageInfo()
this.builderSnapshotStatus = '✅ createFromBuilder(builder) 截图成功:PixelMap ' + imageInfo.size.width + 'x' + imageInfo.size.height
this.snapshotCount++
this.lastError = '(无错)'
} catch (e) {
this.lastError = '❌ createFromBuilder 截图错:' + e.message
}
}
async savePixelMapToFile(pixelMap: image.PixelMap): Promise<string> {
try {
const imagePacker: image.ImagePacker = image.createImagePacker()
const jpegBuffer: ArrayBuffer = await imagePacker.packing(pixelMap, { format: 'image/jpeg', quality: 90 })
imagePacker.release()
const context = getContext(this)
const cacheDir: string = context.cacheDir
const filePath: string = cacheDir + '/snapshot_' + Date.now() + '.jpeg'
const fileFd: number = fs.openSync(filePath, fs.OpenMode.CREATE | fs.OpenMode.WRITE_ONLY).fd
fs.writeSync(fileFd, jpegBuffer)
fs.closeSync(fileFd)
return filePath
} catch (e) {
this.lastError = '❌ savePixelMapToFile 错:' + e.message
return '(存文件失败)'
}
}
async demonstrateSnapshotAndSave() {
try {
const pixelMap: image.PixelMap = await componentSnapshot.get('snapshotTarget')
const filePath: string = await this.savePixelMapToFile(pixelMap)
this.savedFilePath = filePath
this.log = '✅ get(id) 截图 + image.createImagePacker() 打包 JPEG + fs.writeSync 存文件:' + filePath
this.snapshotCount++
this.lastError = '(无错)'
} catch (e) {
this.lastError = '❌ 截图存文件错:' + e.message
}
}
build() {
Column({ space: 8 }) {
Text('鸿蒙 6.1 arkui.componentSnapshot 组件截图坑')
.fontSize(18).fontWeight(FontWeight.Bold).margin({ top: 16, bottom: 4 })
Text('get/getSync/createFromBuilder 返回 image.PixelMap 根因')
.fontSize(11).fontColor('#888').margin({ bottom: 8 })
Column({ space: 4 }) {
Text('截图目标组件(id=snapshotTarget)').fontSize(12).fontColor('#dc3545').fontWeight(FontWeight.Bold)
Text('componentSnapshot.get("snapshotTarget") 截这个 Column').fontSize(9).fontColor('#888')
Row({ space: 8 }) {
Text('左上').fontSize(10).fontColor('#2563eb')
Text('右上').fontSize(10).fontColor('#ff6600')
}
Row({ space: 8 }) {
Text('左下').fontSize(10).fontColor('#28a745')
Text('右下').fontSize(10).fontColor('#ffc107')
}
}
.id('snapshotTarget')
.width('80%')
.padding(12)
.backgroundColor('#f8d7da')
.borderRadius(8)
.border({ width: 2, color: '#dc3545' })
Column({ space: 6 }) {
Text('场景 1:componentSnapshot.get(id) 异步截图(API 10,返回 Promise<image.PixelMap>)')
.fontSize(12).fontColor('#2563eb').fontWeight(FontWeight.Bold)
Text('get 是 async 返回 Promise<image.PixelMap>,不是 sync 返回 dataURL 字符串')
.fontSize(9).fontColor('#888')
Button('① get(id) 异步截图').height(30).fontSize(9).backgroundColor('#2563eb20')
.onClick(() => this.demonstrateAsyncSnapshot())
Text(this.snapshotStatus).fontSize(9).fontColor('#2563eb').margin({ top: 4 })
Text(`PixelMap 尺寸:${this.pixelMapWidth}x${this.pixelMapHeight}`).fontSize(8).fontColor('#2563eb').margin({ top: 2 })
}
.width('92%').padding(8).backgroundColor('#e0f0ff').borderRadius(8)
Column({ space: 6 }) {
Text('场景 2:componentSnapshot.getSync(id) 同步截图(API 12,返回 image.PixelMap)')
.fontSize(12).fontColor('#ff6600').fontWeight(FontWeight.Bold)
Text('getSync 是 API 12+ 同步方法,直接返回 image.PixelMap 不用 await')
.fontSize(9).fontColor('#888')
Button('② getSync(id) 同步截图').height(30).fontSize(9).backgroundColor('#ff660020')
.onClick(() => this.demonstrateSyncSnapshot())
Text(this.syncSnapshotStatus).fontSize(9).fontColor('#ff6600').margin({ top: 4 })
}
.width('92%').padding(8).backgroundColor('#fff3e0').borderRadius(8)
Column({ space: 6 }) {
Text('场景 3:createFromBuilder(builder) 从 CustomBuilder 截图(API 10)')
.fontSize(12).fontColor('#28a745').fontWeight(FontWeight.Bold)
Text('builder 参数是 CustomBuilder 类型(@Builder 装饰的函数),不是 Component')
.fontSize(9).fontColor('#888')
Button('③ createFromBuilder 截图').height(30).fontSize(9).backgroundColor('#28a74520')
.onClick(() => this.demonstrateBuilderSnapshot())
Text(this.builderSnapshotStatus).fontSize(9).fontColor('#28a745').margin({ top: 4 })
}
.width('92%').padding(8).backgroundColor('#d4edda').borderRadius(8)
Column({ space: 6 }) {
Text('场景 4:截图 + 存文件(image.createImagePacker + fs.writeSync)')
.fontSize(12).fontColor('#dc3545').fontWeight(FontWeight.Bold)
Text('PixelMap → image.createImagePacker().packing JPEG buffer → fs.writeSync 存文件')
.fontSize(9).fontColor('#888')
Button('⑦ 截图存文件').height(30).fontSize(9).backgroundColor('#dc354520')
.onClick(() => this.demonstrateSnapshotAndSave())
Text(`存文件路径:${this.savedFilePath}`).fontSize(8).fontColor('#dc3545').margin({ top: 4 })
}
.width('92%').padding(8).backgroundColor('#f8d7da').borderRadius(8)
Column({ space: 3 }) {
Text('鸿蒙 6.1 arkui.componentSnapshot 组件截图坑要点')
.fontSize(10).fontColor('#6c757d').fontWeight(FontWeight.Bold)
Text('① @ohos.arkui.componentSnapshot namespace API 10+(鸿蒙 6.1 API 23 基座)')
.fontSize(8).fontColor('#2563eb')
Text('② get(id): Promise<image.PixelMap> 异步截图(返回 Promise<image.PixelMap> 不是 dataURL)')
.fontSize(8).fontColor('#ff6600')
Text('③ getSync(id): image.PixelMap 同步截图(API 12+,直接返回不用 await)')
.fontSize(8).fontColor('#28a745')
Text('④ createFromBuilder(builder): Promise<image.PixelMap> 从 CustomBuilder 截图')
.fontSize(8).fontColor('#dc3545')
Text('⑤ 鸿蒙坑:get 返回 Promise<image.PixelMap>,React html2canvas 返回 dataURL 字符串')
.fontSize(8).fontColor('#dc3545')
Text('⑥ image.PixelMap 是像素图不是 dataURL——有 getImageInfo/getPixelBytes 可读像素')
.fontSize(8).fontColor('#2563eb')
Text('⑦ PixelMap 存文件:image.createImagePacker().packing(buffer) + fs.writeSync(fd, buffer)')
.fontSize(8).fontColor('#ff6600')
Text('⑧ createFromBuilder 的 builder 参数是 CustomBuilder(@Builder 函数),不是 Component')
.fontSize(8).fontColor('#28a745')
Text('⑨ SnapshotOptions(API 15+):SnapshotRegion/left/right/top/bottom 矩形区域截图')
.fontSize(8).fontColor('#6c757d')
Text('⑩ React 对比:componentSnapshot 不是 html2canvas——鸿蒙返回 PixelMap 像素图不是 dataURL')
.fontSize(8).fontColor('#17a2b8')
}
.width('92%').padding(6).backgroundColor('#f8f9fa').borderRadius(8)
Row({ space: 12 }) {
Text(`截图次数: ${this.snapshotCount}`).fontSize(9).fontColor('#28a745')
Text(`PixelMap: ${this.pixelMapWidth}x${this.pixelMapHeight}`).fontSize(9).fontColor('#2563eb')
}
.margin({ top: 6 })
Text(`日志:${this.log}`).fontSize(9).fontColor('#333').margin({ top: 6 })
Text(`错误:${this.lastError}`).fontSize(8).fontColor('#dc3545').margin({ top: 2 })
Text('鸿蒙 6.1(API 10+)arkui.componentSnapshot:get/getSync/createFromBuilder 返回 image.PixelMap 像素图')
.fontSize(8).fontColor('#6c757d').margin({ top: 6 })
}
.width('100%').height('100%').alignItems(HorizontalAlign.Center)
}
}
写鸿蒙 ArkUI 记住:componentSnapshot 不是 html2canvas 是「返回 image.PixelMap 像素图」——鸿蒙 6.1 API 23
@ohos.arkui.componentSnapshotnamespace(API 10+,鸿蒙 6.1 API 23 基座,SysCap SystemCapability.ArkUI.ArkUI.Full,@crossplatform @atomicservice)。根因不是 dataURL 字符串是 PixelMap 像素图——import componentSnapshot from(✅ default import,❌import { componentSnapshot } from编译错has no exported member),get(id): Promise<image.PixelMap>异步截图(API 10+,返回 Promise<image.PixelMap> 像素图不是 dataURL 字符串,image.PixelMap 有 getImageInfo/getPixelBytes/release 可读像素),getSync(id): image.PixelMap同步截图(API 12+,直接返回 image.PixelMap 不用 await 不是 Promise),createFromBuilder(builder: CustomBuilder): Promise<image.PixelMap>从 CustomBuilder 截图(builder 参数是@Builder装饰的函数引用不是 Component 实例,有 delay/checkImageStatus/options 参数),image.createImagePacker().packing(pixelMap, { format: 'image/jpeg', quality: 90 })打包 PixelMap 为 JPEG buffer(format 是'image/jpeg'不是'jpeg'),fs.writeSync(fd, buffer)写文件(第一参传file.fd文件描述符,是 namespace 顶层函数不是 File 实例方法)。componentSnapshot 返回 image.PixelMap 像素图不是 dataURL 字符串是鸿蒙 6.1 arkui.componentSnapshot 组件截图坑核心!
更多推荐




所有评论(0)