【HarmonyOS】 鸿蒙图片或视频保存相册

【HarmonyOS】 鸿蒙图片或视频保存相册

前言

鸿蒙中保存图片或者视频,或者其他媒体文件到设备的媒体库,可以是相册,也可以是文件管理等。共有两种方式:

  1. 需要应用申请受限权限,获取文件读写的权限(调用需要ohos.permission.READ_IMAGEVIDEO和ohos.permission.WRITE_IMAGEVIDEO的权限),这样就可以将媒体资源(图片or视频or等等)保存到媒体库。
  2. 通过安全控件,用户触发后表示同意,可以临时授权给应用就行保存处理。

关于第二种安全控件,又分为saveButton保存按钮showAssetsCreationDialog授权弹框两种形式。前者的按钮样式不能自定义,所以后者以弹框的形式,让用户操作,触发入口的样式,应用就可以自定义了。后者算是前者的一种替代补充。

一、保存图片和视频授权示例

需要申请"ohos.permission.READ_IMAGEVIDEO"和"ohos.permission.WRITE_IMAGEVIDEO"权限。该权限是管制权限,需要你的应用去通过场景申请【申请使用受限权限

配置权限READ_IMAGEVIDEO,WRITE_IMAGEVIDEO

dart 复制代码
"requestPermissions": [
  {
    "name": "ohos.permission.READ_IMAGEVIDEO",
    "usedScene": {
      "abilities": [
        "EntryAbility"
      ],
      "when": "inuse"
    },
    "reason": "$string:CAMERA"
  },
  {
    "name": "ohos.permission.WRITE_IMAGEVIDEO",
    "usedScene": {
      "abilities": [
        "EntryAbility"
      ],
      "when": "inuse"
    },
    "reason": "$string:CAMERA"
  }
]

向用户申请权限

dart 复制代码
  //  创建申请权限明细
  async reqPermissionsFromUser(): Promise<number[]> {
    let context = getContext() as common.UIAbilityContext;
    let atManager = abilityAccessCtrl.createAtManager();
    let grantStatus = await atManager.requestPermissionsFromUser(context, ['ohos.permission.READ_IMAGEVIDEO','ohos.permission.WRITE_IMAGEVIDEO']);
    return grantStatus.authResults;
  }

  // 用户申请权限
  async requestPermission() {
    let grantStatus = await this.reqPermissionsFromUser();
    for (let i = 0; i < grantStatus.length; i++) {
      if (grantStatus[i] === 0) {
        // 用户授权,可以继续访问目标操作



      }
    }
  }

保存图片到媒体库

dart 复制代码
public async savePicture(buffer: ArrayBuffer): Promise<void> {
  let helper : photoAccessHelper.PhotoAccessHelper = photoAccessHelper.getPhotoAccessHelper(getContext(this) as common.UIAbilityContext);
  let options: photoAccessHelper.CreateOptions = {
    title: Date.now().toString()
  };
  let photoUri: string = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg', options);
  console.info(photoUri)
  // createAsset的调用需要ohos.permission.READ_IMAGEVIDEO和ohos.permission.WRITE_IMAGEVIDEO的权限
  let file: fs.File = fs.openSync(photoUri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
  await fs.write(file.fd, buffer);
  fs.closeSync(file);
}

二、saveButton示例

dart 复制代码
import { photoAccessHelper } from '@kit.MediaLibraryKit';

@Entry
@Component
struct saveButtonExample {
    saveButtonOptions: SaveButtonOptions = {
    icon: SaveIconStyle.FULL_FILLED,
    text: SaveDescription.SAVE_IMAGE,
    buttonType: ButtonType.Capsule
  } // 设置安全控件按钮属性

  build() {
    Row() {
      Column() {
        SaveButton(this.saveButtonOptions) // 创建安全控件按钮
          .onClick(async (event, result: SaveButtonOnClickResult) => {
             if (result == SaveButtonOnClickResult.SUCCESS) {
               try {
                 let context = getContext();
                 let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
                 // 需要确保fileUri对应的资源存在
                 let fileUri = 'file://com.example.temptest/data/storage/el2/base/haps/entry/files/test.jpg';
                 let assetChangeRequest: photoAccessHelper.MediaAssetChangeRequest = photoAccessHelper.MediaAssetChangeRequest.createImageAssetRequest(context, fileUri);
                 await phAccessHelper.applyChanges(assetChangeRequest);
                 console.info('createAsset successfully, uri: ' + assetChangeRequest.getAsset().uri);
               } catch (err) {
                 console.error(`create asset failed with error: ${err.code}, ${err.message}`);
               }
             } else {
               console.error('SaveButtonOnClickResult create asset failed');
             }
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

三、 showAssetsCreationDialog示例

dart 复制代码
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { fileIo } from '@kit.CoreFileKit';

let context = getContext(this);
let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);

async function showAssetsCreationDialogExample() {
  try {
    // 指定待保存到媒体库的位于应用沙箱的图片uri
    let srcFileUri = 'file://com.example.temptest/data/storage/el2/base/haps/entry/files/test.jpg';
    let srcFileUris: Array<string> = [
      srcFileUri
    ];
    // 指定待保存照片的创建选项,包括文件后缀和照片类型,标题和照片子类型可选
    let photoCreationConfigs: Array<photoAccessHelper.PhotoCreationConfig> = [
      {
        title: 'test', // 可选
        fileNameExtension: 'jpg',
        photoType: photoAccessHelper.PhotoType.IMAGE,
        subtype: photoAccessHelper.PhotoSubtype.DEFAULT, // 可选
      }
    ];
    // 基于弹窗授权的方式获取媒体库的目标uri
    let desFileUris: Array<string> = await phAccessHelper.showAssetsCreationDialog(srcFileUris, photoCreationConfigs);
    // 将来源于应用沙箱的照片内容写入媒体库的目标uri
    let desFile: fileIo.File = await fileIo.open(desFileUris[0], fileIo.OpenMode.WRITE_ONLY);
    let srcFile: fileIo.File = await fileIo.open(srcFileUri, fileIo.OpenMode.READ_ONLY);
    await fileIo.copyFile(srcFile.fd, desFile.fd);
    fileIo.closeSync(srcFile);
    fileIo.closeSync(desFile);
    console.info('create asset by dialog successfully');
  } catch (err) {
    console.error(`failed to create asset by dialog successfully errCode is: ${err.code}, ${err.message}`);
  }
}

注意: 1. 使用createAsset需要指定是视频还是图片, fileio.open并不校验文件内容 2. 使用createImageAssetRequest接口,如果要保存视频需要用createVideoeAssetRequest 或者还可以直接使用createAssetRequest和addResource的方式

相关推荐
Charlie_lll几秒前
学习Three.js–基于GeoJSON绘制2D矢量地图
前端·three.js
小二·18 分钟前
Python Web 开发进阶实战:AI 原生安全防护 —— 在 Flask + Suricata 中构建智能网络威胁狩猎平台
前端·人工智能·python
葡萄城技术团队24 分钟前
SpreadJS V19.0 新特性解密:设计器容器行列合计,让报表数据汇总更灵活
前端
晚霞的不甘25 分钟前
Flutter for OpenHarmony:从零到一:构建购物APP的骨架与精美UI
前端·javascript·flutter·ui·前端框架·鸿蒙
小二·38 分钟前
Python Web 开发进阶实战:AI 原生硬件接口 —— 在 Flask + MicroPython 中构建边缘智能设备控制平台
前端·人工智能·python
ElasticPDF-新国产PDF编辑器44 分钟前
基于 PDF.js 的 PDF 文字编辑解决方案,纯前端 SDK,跨平台、框架无关、Web 原生
前端·javascript·pdf
带带弟弟学爬虫__1 小时前
速通新Baidu Frida检测
前端·javascript·vue.js·python·网络爬虫
b2077211 小时前
Flutter for OpenHarmony 身体健康状况记录App实战 - 运动分析实现
python·flutter·harmonyos
好学且牛逼的马1 小时前
ES6 核心语法精讲
前端·ecmascript·es6
GISer_Jing1 小时前
一次编码,七端运行:Taro多端统一架构深度解析与电商实战
前端·aigc·taro