HarmonyOS鸿蒙Next中base64格式的图片数据如何保存文件到本地相册

发布于 1周前 作者 songsunli 来自 鸿蒙OS

HarmonyOS鸿蒙Next中base64格式的图片数据如何保存文件到本地相册 base64格式的图片数据如何保存文件到本地相册
我这边是前端调交互方法把获取到的base64图片的字符串传给原生端,原生端拿到数据之后保存图片到本地

3 回复

先把base64转成文件流,然后使用@ohos.file.fs的fs.write方法先把图片写到自己的项目目录里面,然后在使用@ohos.file.picker读取目录里面的图片,保存到用户手机上。 参考示例如下:

saveImage() {
  let uri = '';
  try {
    let PhotoSaveOptions = new picker.PhotoSaveOptions();
    //保存图片默认名称 
    PhotoSaveOptions.newFileNames = ['test.png'];
    let photoPicker = new picker.PhotoViewPicker();
    //调起系统的图片保存功能 
    photoPicker.save(PhotoSaveOptions).then((PhotoSaveResult) => {
      uri = PhotoSaveResult[0];
      //获取图片的base64字符串 
      let imageStr = '图片的base64字符串'.split(',');
      //打开文件
      let file = fs.openSync(uri, fs.OpenMode.READ_WRITE);
      //base64字符串转成
      const decodeBuffer = buffer.from(imageStr, 'base64').buffer;
      //写入文件 
      fs.writeSync(file.fd, decodeBuffer);
      //关闭文件
      fs.closeSync(file);
    }).catch((err: Error) => {
      console.error(err + '');
    })
  }
  catch (e) {
    console.error(e);
  }
}

图片保存到相册,可以通过2种方式实现。方案一:可以通过安全控件「保存控件(SaveButton)」实现。该控件对应媒体库写入特权。应用集成保存控件后,用户点击该控件,应用会获取10秒内单次访问媒体库特权接口的授权。

方案一参考代码:

import { photoAccessHelper } from '@kit.MediaLibraryKit';
import fs from '@ohos.file.fs';
import { http } from '@kit.NetworkKit';
import { promptAction } from '@kit.ArkUI';

/**
* 参考资料:
* https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/photoaccesshelper-resource-guidelines-0000001774280306-V5#ZH-CN_TOPIC_0000001881258417__使用安全控件创建媒体资源
*/
@Entry
@Component struct Index {
  @State message: string = 'Hello World'
  @State saveButtonOptions: SaveButtonOptions = {
    icon: SaveIconStyle.FULL_FILLED,
    text: SaveDescription.SAVE_IMAGE,
    buttonType: ButtonType.Capsule
  }
  // 设置安全控件按钮属性
  build() {
    Row() {
      Column() {
        Text(this.message).fontSize(50).fontWeight(FontWeight.Bold)
        SaveButton(this.saveButtonOptions)
          // 创建安全控件按钮
          .onClick(async (event, result: SaveButtonOnClickResult) => {
            if (result == SaveButtonOnClickResult.SUCCESS) {
              let context = getContext();
              //获取相册管理模块的实例,用于访问和修改相册中的媒体文件 let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context); 
              // onClick触发后10秒内通过createAsset接口创建图片文件,10秒后createAsset权限收回
              let uri = await phAccessHelper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg');
              // 创建媒体文件
              console.info('createAsset successfully, uri: ' + uri);
              let file = fs.openSync(uri, fs.OpenMode.READ_WRITE || fs.OpenMode.CREATE);
              let totalSize = 0;
              let httpRequest = http.createHttp();
              httpRequest.on("dataReceive", (data: ArrayBuffer) => {
                let writeLen = fs.writeSync(file.fd, data); totalSize = totalSize + writeLen;
              });
              httpRequest.requestInStream('https://developer.huawei.com/allianceCmsResource/resource/HUAWEI_Developer_VUE/images/homeNew/next-pc.png', { method: http.RequestMethod.GET, connectTimeout: 3000, }, httpCode => {
                console.info('requestInStream HTTP CODE is', httpCode)
              })
              httpRequest.on("dataEnd", () => {
                fs.close(file);
                promptAction.showMessageDialog({ title: "下载图片结束,并保存至相册", message: `图片大小:${totalSize}字节` })
              })
            } else {
              console.error('SaveButtonOnClickResult create asset failed');
            }
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

方案二:通过申请ACL权限。需要在module.json5文件中配置ohos.permission.WRITE_IMAGEVIDEO权限。类似这样:

{
  // 允许修改用户公共目录的图片或视频文件。
  "name": "ohos.permission.WRITE_IMAGEVIDEO",
  "reason": "$string:internet_permission_reason",
  "usedScene": {
    "when": "always"
  }
}

方案二参考代码:

import { abilityAccessCtrl, common } from '@kit.AbilityKit';
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import fs from '@ohos.file.fs';
import { http } from '@kit.NetworkKit';
import { promptAction } from '@kit.ArkUI';

@Entry
@Component struct Index {
  @State message: string = 'Hello World' private appContext: common.Context = getContext(this);
  private atManager = abilityAccessCtrl.createAtManager();
  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
        Button("保存图片")
          .margin({ top: 10 })
          .onClick(async (event: ClickEvent) => {
            //申请权限并保存图片到图库
            try {
              //申请相册管理模块权限
              'ohos.permission.WRITE_IMAGEVIDEO' this.atManager.requestPermissionsFromUser(this.appContext, ['ohos.permission.WRITE_IMAGEVIDEO']).then(async () => {
                //权限申请成功,保存到图库
                let context = getContext();
                //获取相册管理模块的实例,用于访问和修改相册中的媒体文件
                let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
                // onClick触发后10秒内通过createAsset接口创建图片文件,10秒后createAsset权限收回
                let uri = await phAccessHelper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg');
                // 创建媒体文件
                console.info('createAsset successfully, uri: ' + uri);
                let file = fs.openSync(uri, fs.OpenMode.READ_WRITE || fs.OpenMode.CREATE);
                let totalSize = 0;
                let httpRequest = http.createHttp();
                httpRequest.on("dataReceive", (data: ArrayBuffer) => {
                  let writeLen = fs.writeSync(file.fd, data);
                  totalSize = totalSize + writeLen;
                });
                httpRequest.requestInStream('https://developer.huawei.com/allianceCmsResource/resource/HUAWEI_Developer_VUE/images/homeNew/next-pc.png', { method: http.RequestMethod.GET, connectTimeout: 3000, }, httpCode => {
                  console.info('requestInStream HTTP CODE is', httpCode)
                })
                httpRequest.on("dataEnd", () => {
                  fs.close(file);
                  promptAction.showMessageDialog({ title: "下载图片结束,并保存至相册", message: `图片大小:${totalSize}字节` })
                })
              })
            } catch (err) {
              console.error(`requestPermissionsFromUser call Failed! error: ${err.code}`);
            }
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

更多关于HarmonyOS鸿蒙Next中base64格式的图片数据如何保存文件到本地相册的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,将base64格式的图片数据保存到本地相册可以通过以下步骤实现:

  1. 解码base64数据:首先,使用Base64类将base64字符串解码为字节数组。
  2. 创建文件:在应用的沙盒目录或外部存储目录中创建一个文件,用于保存图片数据。
  3. 写入文件:将解码后的字节数组写入到创建的文件中。
  4. 添加到相册:使用MediaLibrary API将文件添加到设备的相册中。

具体代码如下:

import mediaLibrary from '@ohos.multimedia.mediaLibrary';
import fileio from '@ohos.fileio';
import Base64 from '@ohos.util';

async function saveBase64ImageToGallery(base64Data: string, fileName: string) {
    // 解码base64数据
    const byteArray = Base64.decode(base64Data);

    // 获取媒体库实例
    const media = mediaLibrary.getMediaLibrary();

    // 创建文件
    const filePath = await media.createAsset(mediaLibrary.MediaType.IMAGE, fileName, fileio.DirectoryType.DIR_PICTURES);

    // 写入文件
    const file = await fileio.open(filePath, fileio.OpenMode.WRITE_ONLY);
    await fileio.write(file.fd, byteArray);
    await fileio.close(file.fd);

    // 添加到相册
    await media.addAssetToAlbum(filePath);
}

此代码片段展示了如何将base64格式的图片数据保存到本地相册。

在HarmonyOS鸿蒙Next中,要将Base64格式的图片数据保存到本地相册,可以按照以下步骤操作:

  1. 将Base64字符串解码为字节数组。
  2. 使用@ohos.file.fs模块将字节数组写入临时文件。
  3. 使用@ohos.file.photoAccessHelper模块将临时文件移动到相册中。

示例代码:

import photoAccessHelper from '@ohos.file.photoAccessHelper';
import fs from '@ohos.file.fs';

async function saveBase64ToGallery(base64Data) {
  // 解码Base64
  const byteArray = base64ToArrayBuffer(base64Data);
  
  // 写入临时文件
  const tempFilePath = '临时文件路径';
  await fs.writeFile(tempFilePath, byteArray);
  
  // 移动到相册
  const phAccessHelper = photoAccessHelper.getPhotoAccessHelper();
  await phAccessHelper.createAsset(tempFilePath);
}

function base64ToArrayBuffer(base64) {
  const binaryString = atob(base64);
  const len = binaryString.length;
  const bytes = new Uint8Array(len);
  for (let i = 0; i < len; i++) {
    bytes[i] = binaryString.charCodeAt(i);
  }
  return bytes.buffer;
}

注意:需要申请相册读写权限。

回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!