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

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

六、总结

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

相关推荐
鸿蒙开发工程师—阿辉9 小时前
HarmonyOS 应用拉起系列(一):应用与元服务互通方式
华为·harmonyos·arkts·鸿蒙
simple_lau3 天前
鸿蒙 3D 开发实战:从模型加载到动画管理的完整实现
harmonyos·arkts·arkui
儿歌八万首10 天前
鸿蒙ArkTS多环境API管理与安全签名方案实践
安全·harmonyos·arkts·签名
SuperHeroWu711 天前
【HarmonyOS】ArkTS语法详细解析
华为·harmonyos·arkts·鸿蒙·编程语言·语法·详解
NoirSeeker15 天前
在windows平台上基于OpenHarmony sdk编译三方库并暴露给ArkTS使用(详细)
c++·windows·arkts·鸿蒙·交叉编译
Keya23 天前
在HarmonyOS(鸿蒙)中H5页面中的视频不会自动播放
app·harmonyos·arkts
儿歌八万首23 天前
HarmonyOS中各种动画的使用介绍
华为·harmonyos·arkts·arkui
逻极24 天前
HarmonyOS从入门到精通:自定义组件开发指南(二):组件属性与参数传递
华为·harmonyos·arkts·鸿蒙·自定义组件
simple丶1 个月前
【HarmonyOS】封装用户鉴权工具类
harmonyos·arkts·arkui
simple丶1 个月前
【HarmonyOS】基于Axios封装网络请求工具类
harmonyos·arkts·arkui