HarmoneyOS使用媒体文件管理服务实现图片压缩

66 阅读4分钟

Media Library Kit 简介

Media Library Kit(媒体文件管理服务)提供了管理相册和媒体文件的能力,包括照片和视频,帮助你的应用快速构建图片视频展示和播放能力。

官方提供了很多API,此文仅涉及图库相册

使用媒体文件管理服务需要配置和申请权限

相册管理模块的读写操作需要相应权限,在申请权限前,请保证符合权限使用的基本原则

权限名说明授权方式
ohos.permission.READ_IMAGEVIDEO允许应用读取媒体库的图片和视频媒体文件信息。user_grant
ohos.permission.WRITE_IMAGEVIDEO允许应用读写媒体库的图片和视频媒体文件信息。user_grant

关于权限申请还有另一篇文可供参考 HarmonyOS权限管理

获取图片信息

应用通过调用 PhotoAccessHelper.getAssets 获取媒体资源。

前提条件

// 获取图片
async getPhotos() {
  // 相册管理器
  const phAccessHelper = photoAccessHelper.getPhotoAccessHelper(getContext())
  // 相册数据库谓词(筛选条件)
  const predicates = new dataSharePredicates.DataSharePredicates()
  // 根据条件获取资源
  const fetchAssetsResult = await phAccessHelper.getAssets({
    fetchColumns: [],
    predicates: predicates
  })
  // 获取图片资源
  const photoAssets = await fetchAssetsResult.getFirstObject() // 获取第一张图片
}
PhotoKeys 图片/视频信息

枚举,图片和视频文件关键信息。

文档链接:docs.openharmony.cn/pages/v4.1/…

获取图片大小(图片信息)
  1. 在 fetchColumns 中添加属性字段
  2. 用 get 接口去获取属性,返回值为联合类型,通过 as 断言指定类型
// 获取图片
async getPhotos() {
  // 相册管理器
  const phAccessHelper = photoAccessHelper.getPhotoAccessHelper(getContext())
  // 相册数据库谓词(条件)
  const predicates = new dataSharePredicates.DataSharePredicates()
  // 根据条件获取资源
  const fetchAssetsResult = await phAccessHelper.getAssets({
    fetchColumns: [photoAccessHelper.PhotoKeys.SIZE],        // 1. 添加 SIZE 字段
    predicates: predicates
  })
  // 获取图片资源
  const photoAssets = await fetchAssetsResult.getFirstObject() // 获取第一个资源
  photoAssets.get(photoAccessHelper.PhotoKeys.SIZE) as number // 2. 获取 SIZE 属性
}
删除照片(放入回收站)

通过 MediaAssetChangeRequest.deleteAssets 可以将文件放入回收站。

实现步骤:

  1. 建立检索条件,用于获取图片资源。
  2. 调用 PhotoAccessHelper.getAssets 接口获取目标图片资源。
  3. 调用 getFirstObject / getAllObjects 接口获取图片,即要放入回收站的图片对象。
  4. 调用MediaAssetChangeRequest.deleteAssets接口将文件放入回收站。
// 删除图片
async deletePhotos() {
  // 1. 建立检索条件,用于获取图片资源。
  const phAccessHelper = photoAccessHelper.getPhotoAccessHelper(getContext())
  const predicates = new dataSharePredicates.DataSharePredicates()
  // 2. 调用 PhotoAccessHelper.getAssets 接口获取目标图片资源。
  const assets = await phAccessHelper.getAssets({
    fetchColumns: [],
    predicates
  })
  // 3. 获取第一张图片资源
  const photoAsset = await assets.getFirstObject()
  // 4. 删除图片的核心代码 deleteAssets,为准备第二个参数 photoAsset,前面需要做很多准备工作
  await photoAccessHelper.MediaAssetChangeRequest.deleteAssets(getContext(), [photoAsset])
}
获取相册信息

docs.openharmony.cn/pages/v4.1/…

// 获取用户相册
async getUserAlbums() {
  // 通过 PhotoAccessHelper.getAlbums 接口获取相册
  const phAccessHelper = photoAccessHelper.getPhotoAccessHelper(getContext())
  // 获取相册对象
  const fetchResultAlbums = await phAccessHelper.getAlbums(
    photoAccessHelper.AlbumType.USER, // 一级相册类型(用户相册,系统相册)
    photoAccessHelper.AlbumSubtype.USER_GENERIC // 二级相册类型(用户相册,收藏夹)
  )
  // 获取所有相册
  const list = await fetchResultAlbums.getAllObjects()
  this.albumList = list
}
压缩图片
  • 创建ImagePacker实例:SystemCapability.Multimedia.Image.ImagePacker
  • 表示图片打包选项:SystemCapability.Multimedia.Image.ImagePacker
  • 图片源类,用于获取图片相关信息:SystemCapability.Multimedia.Image.ImageSource在调用ImageSource的方法前,需要先通过createImageSource构建一个ImageSource实例。
  • 关键API:packing(source: ImageSource, option: PackingOption): Promise 图片压缩或重新打包,使用Promise形式返回结果
参数名类型必填说明
sourceImageSource打包的图片源。
optionPackingOption设置打包参数。
// 压缩图片
async compressImage(uri: string, quality = 20) {
  // ---- 压缩图片 ----
  // 创建图片打包器
  const imagePacker = image.createImagePacker()
  // 坑点:createImageSource 不能直接使用 uri,需要先基于 uri 打开文件,再传入文件的 fd
  const file = fileIo.openSync(uri)
  // createImageSource 传入文件标识 fd,获取图片源
  const imageSource = image.createImageSource(file.fd)
  // 图片打包(图片重新编码)
  //  参数1: 图片源
  //  参数2: 打包配置:格式、质量 为必传参数
  const arrayBuffer = await imagePacker.packing(imageSource, { format: 'image/jpeg', quality: quality })
  // AlertDialog.show({ message: '压缩后文件流大小为:' + formatByteLength(arrayBuffer.byteLength) })
  // ---- 压缩图片 ----

  // ---- 写入图库 ----
  // 把数据流写入图库中,需要使用到 photoAccessHelper 模块
  const phAccessHelper = photoAccessHelper.getPhotoAccessHelper(getContext())
  // 创建图片资产,返回 uri 路径
  const createAssetUri = await phAccessHelper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg')
  // 数据写入图库前,需要先打开图库文件 并 设置打开模式为 可写
  const createAssetFile = fileIo.openSync(createAssetUri, fileIo.OpenMode.READ_WRITE)
  // writeSync 把压缩后的图片数据流,写入到文件中
  fileIo.writeSync(createAssetFile.fd, arrayBuffer)
  // 数据写入完成,关闭文件,释放资源
  fileIo.close(createAssetFile.fd)
  // ---- 写入图库 ----
}