【HarmonyOS ArkTS】获取组件截图并保存到相册

写在前面

本文基于项目中的文件,详细说明组件截图及保存到相册的实现逻辑。 适合 HarmonyOS 开发初学者理解如何在 ArkTS 中完成组件截图、图片保存至缓存路径与图片保存至相册的操作。

一、整体流程

  1. 对特定组件截图
  2. 将图片压缩并写入到缓存目录
  3. 将图片保存到本地相册

二、代码实现

typescript 复制代码
// 模块导入
import { componentSnapshot, promptAction } from "@kit.ArkUI"
import { image } from "@kit.ImageKit"
import { fileIo, fileUri } from "@kit.CoreFileKit"
import { photoAccessHelper } from "@kit.MediaLibraryKit"

async saveImg() {
  // 1. 对特定组件截图
  const pixelMap = await componentSnapshot.get('share')
  
  // 2. 将图片压缩并写入到缓存目录
  const packer = image.createImagePacker()
  const arrayBuffer = await packer.packToData(pixelMap, { format: 'image/jpeg', quality: 70 })
  const cxt = getContext()
  const imgPath = cxt.cacheDir + '/' + Date.now() + '.jpeg'
  const imgFile =
    fileIo.openSync(imgPath, fileIo.OpenMode.CREATE | fileIo.OpenMode.READ_WRITE)
  fileIo.closeSync(imgFile)
  
  // 3. 将图片保存到本地相册
  const imgUri = fileUri.getUriFromPath(imgPath)
  const request = photoAccessHelper.MediaAssetChangeRequest.createImageAssetRequest(cxt, imgUri)
  const helper = photoAccessHelper.getPhotoAccessHelper(cxt)
  await helper.applyChanges(request)

  promptAction.showToast({ message: '图片已保存到本地' })
}

三、结构说明

1. 对特定组件截图

typescript 复制代码
import { componentSnapshot } from "@kit.ArkUI"

@Component
struct PreviewComponent {
  @State id: string = 'share';

  build() {
    Column() {
      // 需要截图的组件
      Image($r('app.media.banner'))
        .id(this.id)
        
      Button('保存截图')
        .onClick(() => this.saveImg())
    }
  }

 async saveImg() {
   // 1. 对特定组件截图
   const pixelMap = await componentSnapshot.get('share')

  //......
 }
}

说明:

  • 将需要截图的组件的id填入componentSnapshot.get的参数中
  • 结果为pixelMap格式的图片数据

2. 将图片压缩并写入到缓存目录

typescript 复制代码
import { image } from "@kit.ImageKit"
import { fileIo } from "@kit.CoreFileKit"


async saveImg() {
  //......
  
  // 2. 将图片压缩并写入到缓存目录
  // image.createImagePacker()函数的返回值是ImagePacker对象
  const packer = image.createImagePacker()
  // 将图片压缩或重新编码,返回的结果为二进制数据流
  const arrayBuffer = await packer.packToData(pixelMap, { format: 'image/jpeg', quality: 70 }) // 图片质量(1-100)

  // 获取缓存路径
  const cxt = getContext()
  const imgPath = cxt.cacheDir + '/' + Date.now() + '.jpeg'

  // 创建临时文件对象,给fileIo创建和写入权限,写入压缩后的图片数据
  const imgFile =
    fileIo.openSync(imgPath, fileIo.OpenMode.CREATE | fileIo.OpenMode.READ_WRITE)
  // 将图片写入到缓存路径
  fileIo.writeSync(imgFile.fd, arrayBuffer)
  // 关闭后file对象不再具备实际意义 不可再用于进行读写等操作
  fileIo.closeSync(imgFile)

  //......
}

说明:

  • 使用 ImagePacker 对pixelMap格式数据进行压缩并打包
  • 使用 fileIo 模块将图片写入到缓存目录
  • 操作完后注意关闭file对象

3. 将图片保存到本地相册

typescript 复制代码
import { promptAction } from "@kit.ArkUI"
import { fileUri } from "@kit.CoreFileKit"
import { photoAccessHelper } from "@kit.MediaLibraryKit"

async saveImg() {
  //......
  
  // 3. 将图片保存到本地相册
  // 获取图片的完整路径( getContext获取的是部分路径 )
  const imgUri = fileUri.getUriFromPath(imgPath)
  // 创建一个 向相册发送修改数据 的请求
  const request = photoAccessHelper.MediaAssetChangeRequest.createImageAssetRequest(cxt, imgUri)

  // 获取照片访问助手实例,用于接收请求
  const helper = photoAccessHelper.getPhotoAccessHelper(cxt)

  // 调用助手实例上的方法, 将图片保存到本地 ( 需要相册的相关权限 )
  await helper.applyChanges(request)

  promptAction.showToast({ message: '图片已保存到本地' })
}

说明:

  • 使用 fileUri 获取图片的完整路径
  • 通过 photoAccessHelper 模块得到修改请求和图片访问助手
  • 将图片保存到本地 ( 需要相册的相关权限 )

四、相关模块说明

模块 功能
componentSnapshot 对已渲染的组件进行截图
promptAction 创建并显示文本提示框
image 提供图片的解码和编码能力
fileIo 提供文件存储管理能力
fileUri 通过PATH获取文件统一资源标志符
photoAccessHelper 提供相册管理能力

五、补充

如果没有向用户申请相册的相关权限,我们也可以用华为内置的安全控件完成保存功能,此时用户通过点击该保存按钮,可以临时获取存储权限,而不需要权限弹框授权确认。

typescript 复制代码
// 
 SaveButton({
          text: SaveDescription.SAVE_IMAGE,
          buttonType: ButtonType.Normal,
          icon: SaveIconStyle.FULL_FILLED
        })
          .onClick((event, result) => {
            if (result == SaveButtonOnClickResult.SUCCESS) {
              this.saveImg()
              // 自己关自己
              this.controller.close()
            }
          })

为了保障用户的隐私不被恶意应用获取,华为针对安全控件作了很多的限制,比如其对象参数内属性的值都是枚举,开发者并不能对其样式做过多更改。

六、总结

本文提供了一个获取组件截图并保存到相册的主要流程,并提供了一个临时获取相册存储权限的方式,希望能帮助开发者快速掌握保存图片的核心代码实现。

相关推荐
知然2 天前
鸿蒙 Native API 的封装库 h2lib_arkbinder
c++·arkts·鸿蒙
半醉看夕阳4 天前
HarmonyOS开发 ArkTS 之 var 、let、const 变量声明的剖析
typescript·harmonyos·arkts
我睡醒再说4 天前
HarmonyOS5 运动健康app(二):健康跑步(附代码)
华为·信息可视化·harmonyos·arkts·应用开发
lucky志5 天前
探秘鸿蒙 HarmonyOS NEXT:鸿蒙定时器,简单倒计时的场景应用
arkts·harmonyos next
libo_20255 天前
HarmonyOS 5 模型瘦身验证:从200MB到5MB的剪枝后准确率回归测试
ai编程·arkts
libo_20255 天前
HarmonyOS5 分布式数据库测试:如何验证10万条数据跨设备同步的一致性
arkts
libo_20256 天前
HarmonyOS5 响应式编程内建支持:仓颉的signal与computed原语解析
arkts
libo_20256 天前
HarmonyOS5 折叠屏适配:仓颉语言的@Foldable作用域如何自动处理状态切换
arkts
libo_20256 天前
HarmonyOS5 编译期优化:仓颉的constexpr计算在布局渲染中的提速实践
arkts