HarmonyOS鸿蒙Next中如何把base64的图片保存到相册

HarmonyOS鸿蒙Next中如何把base64的图片保存到相册 如何把base64的图片保存到相册

6 回复

先把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.showDialog({
                  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 = this.getContext();
  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.showDialog({
                      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


下载base64图片到相册

注意1:有些base64的格式图片显示不出来, 是因为前缀没加data:image/png;base64,

注意2:下载到相册的base64字符串不能有’data:image/jpeg;base64,'这样的前缀。所以我这里用正则去掉了前缀

phAccessHelper.createAsset(photoAccessHelper.PhotoType.IMAGE, ‘jpg’);调用不就需要受限权限?

需要权限:ohos.permission.WRITE_IMAGEVIDEO

在HarmonyOS鸿蒙Next中,将Base64图片保存到相册可以通过以下步骤实现:

  1. Base64解码:首先,将Base64字符串解码为二进制数据。可以使用Base64类提供的解码方法,如Base64.decode()

  2. 创建图片文件:将解码后的二进制数据写入一个临时文件,通常是一个.jpg.png文件。

  3. 保存到相册:使用MediaLibraryAPI将图片文件保存到设备的相册中。可以通过MediaLibrary.getMediaLibrary()获取MediaLibrary实例,然后调用saveMedia()方法将文件保存到相册。

示例代码片段如下:

import mediaLibrary from '@ohos.multimedia.mediaLibrary';
import { Base64 } from '@ohos.base64';

async function saveBase64ImageToGallery(base64String: string) {
    // Step 1: Decode Base64 to binary data
    const binaryData = Base64.decode(base64String);

    // Step 2: Create a temporary image file
    const filePath = 'path/to/temporary/image.jpg';
    await fs.writeFile(filePath, binaryData);

    // Step 3: Save the image to the gallery
    const mediaLib = mediaLibrary.getMediaLibrary();
    await mediaLib.saveMedia(filePath, mediaLibrary.MediaType.IMAGE);
}

这段代码展示了如何将Base64图片保存到相册的基本流程。确保处理文件路径和权限时遵循HarmonyOS的相关规范。

在HarmonyOS鸿蒙Next中,将Base64图片保存到相册的步骤如下:

  1. 解码Base64:使用Base64.decode()方法将Base64字符串解码为字节数组。
  2. 创建文件:在应用的缓存目录或外部存储中创建一个临时文件,并写入解码后的字节数据。
  3. 保存到相册:使用MediaStoreinsertImage()方法将临时文件保存到系统的相册中。

示例代码:

import ohos.media.image.ImagePacker;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.image.common.PixelFormat;
import ohos.media.photokit.photokit.MediaStore;
import ohos.utils.Base64;

// 解码Base64
byte[] imageBytes = Base64.decode(base64String, Base64.DEFAULT);

// 创建临时文件并写入数据
File tempFile = new File(context.getCacheDir(), "temp_image.jpg");
try (FileOutputStream fos = new FileOutputStream(tempFile)) {
    fos.write(imageBytes);
}

// 保存到相册
MediaStore.insertImage(context.getContentResolver(), tempFile.getAbsolutePath(), "Image Title", "Image Description");

确保在config.json中声明了必要的权限,如ohos.permission.WRITE_MEDIA

回到顶部