【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的方式

相关推荐
拾光拾趣录3 分钟前
闭包:从“变量怎么还没死”到写出真正健壮的模块
前端·javascript
拾光拾趣录23 分钟前
for..in 和 Object.keys 的区别:从“遍历对象属性的坑”说起
前端·javascript
OpenTiny社区34 分钟前
把 SearchBox 塞进项目,搜索转化率怒涨 400%?
前端·vue.js·github
编程猪猪侠1 小时前
Tailwind CSS 自定义工具类与主题配置指南
前端·css
qhd吴飞1 小时前
mybatis 差异更新法
java·前端·mybatis
YGY Webgis糕手之路1 小时前
OpenLayers 快速入门(九)Extent 介绍
前端·经验分享·笔记·vue·web
患得患失9492 小时前
【前端】【vueDevTools】使用 vueDevTools 插件并修改默认打开编辑器
前端·编辑器
ReturnTrue8682 小时前
Vue路由状态持久化方案,优雅实现记住表单历史搜索记录!
前端·vue.js
UncleKyrie2 小时前
一个浏览器插件帮你查看Figma设计稿代码图片和转码
前端
遂心_2 小时前
深入解析前后端分离中的 /api 设计:从路由到代理的完整指南
前端·javascript·api