HarmonyOS 保存图片到相册有延时,如何在保存完之后立即刷新相册,需要相关代码的实现

HarmonyOS
2024-12-25 16:55:32
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
Excelsior_abit

保存图片到相册是没有延时的,系统相册不需要刷新。

以下是相关demo参考:

import { common } from '@kit.AbilityKit';
import { fileUri, picker } from '@kit.CoreFileKit';
import fs from '@ohos.file.fs';
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { dataSharePredicates } from '@kit.ArkData';
import { image } from '@kit.ImageKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { promptAction } from '@kit.ArkUI';

// 打包 PixelMap 为 jpg 格式
export async function packingPixelMap2Jpg(pixelMap: PixelMap): Promise<ArrayBuffer> {
  // 创建ImagePacker实例
  const imagePackerApi = image.createImagePacker();
  const packOpts: image.PackingOption = { format: "image/jpeg", quality: 100 };
  let imageBuffer: ArrayBuffer = new ArrayBuffer(1);
  try {
    // 图片压缩或重新打包
    imageBuffer = await imagePackerApi.packing(pixelMap, packOpts);
  } catch (err) {
    console.error(`Invoke packingPixelMap2Jpg failed, err: ${JSON.stringify(err)}`);
  }
  return imageBuffer;
}

@Entry
@Component
struct SavePhotoPage {
  @State imagePath: string = ''
  @State pixelMap:image.PixelMap  | undefined = undefined
  private context = getContext(this) as common.UIAbilityContext;
  @Styles ButtonStyle(){
    .width(150).height(35).margin(8)
  }

  build() {
    Row() {
      Column() {
        Button("选择图片").ButtonStyle()
          .onClick(() => {
            this.selectPhoto()
          })
        Button("保存到文件管理器").ButtonStyle()
          .onClick(() => {
            this.imageWriteFileManager(this.imagePath)
          })
        Row(){
          Button("保存到相册方法一").ButtonStyle()
            .onClick(() => {
              this.imageWriteAlbumExample(this.imagePath)
            })
          Button("保存到相册方法二").ButtonStyle()
            .onClick(() => {
              this.imageWriteAlbumExample2(this.imagePath)
            })
        }
        Image(this.pixelMap)
          .width(300)
          .height(320)
        SaveButton().onClick(async (event:ClickEvent, result:SaveButtonOnClickResult) => {
          if (result == SaveButtonOnClickResult.SUCCESS) {
            try {
              const context = getContext(this);
              let helper = photoAccessHelper.getPhotoAccessHelper(context);
              // onClick触发后10秒内通过createAsset接口创建图片文件,10秒后createAsset权限收回。
              let uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'png');
              // 使用uri打开文件,可以持续写入内容,写入过程不受时间限制
              let resFile = fs.openSync(this.imagePath, fs.OpenMode.READ_ONLY)
              let file = fs.openSync(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
              // 写入文件
              fs.copyFileSync(resFile.fd, file.fd);
              // 关闭文件
              fs.closeSync(file.fd);
              fs.closeSync(resFile.fd);
              promptAction.showToast({
                message: '已保存至相册',
                duration: 2500
              });
            } catch (error) {
              console.error("error is "+ JSON.stringify(error));
            }
          }
        })
      }.width('100%')
    }.height('100%')
  }
  selectPhoto() {
    const photoSelectOptions = new picker.PhotoSelectOptions();
    const photoViewPicker = new picker.PhotoViewPicker();
    photoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE; // 过滤选择媒体文件类型为IMAGE
    photoSelectOptions.maxSelectNumber = 5; // 选择媒体文件的最大数目
    photoViewPicker.select(photoSelectOptions).then(async (photoSelectResult: picker.PhotoSelectResult) => {
      const fileUri = photoSelectResult.photoUris[0]
      //复制到沙箱路径,模拟用户下载图片到沙箱
      this.imagePath = this.getFileInfo(fileUri)
      //转为pixelmap保存
      const imageSource: image.ImageSource = image.createImageSource(this.imagePath);
      this.pixelMap = await imageSource.createPixelMap();
    })
  }

  getFileInfo(filePathString: string): string {
    let resFile = fs.openSync(filePathString, fs.OpenMode.READ_ONLY)
    const dateStr = (new Date().getTime()).toString()
    // 临时文件目录
    let newPath = this.context.filesDir + `/${'Temp'+ resFile.name}`;
    // 转化路径
    fs.copyFileSync(resFile.fd, newPath);
    fs.closeSync(resFile.fd);
    // 新的路径
    let realUri = 'file://' + newPath;
    console.log(realUri)
    return realUri
  }

  async imageWriteAlbumExample(fileUri?:string,pixelMap?:image.PixelMap) {
    console.info('createAssetDemo');
    let context = getContext(this);
    let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
    let photoType: photoAccessHelper.PhotoType = photoAccessHelper.PhotoType.IMAGE;
    let extension:string = 'jpg';
    let options: photoAccessHelper.CreateOptions = {
      title: 'testPhoto'
    }
    let uri = await phAccessHelper.createAsset(photoType, extension, options);
    // 使用uri打开文件,可以持续写入内容,写入过程不受时间限制
    try {
      if(pixelMap){
        let file = await fs.open(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
        const imageBuffer = await packingPixelMap2Jpg(pixelMap as image.PixelMap)
        // 写到媒体库文件中
        fs.writeSync(file.fd, imageBuffer);
        fs.closeSync(file.fd);
      }
      else {
        // 写到媒体库文件中
        let resFile = fs.openSync(fileUri, fs.OpenMode.READ_ONLY)
        let stat = fs.statSync(resFile.fd)
        console.debug("stat size: "+ stat.size)
        let file =  fs.openSync(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
        // 内容复制到媒体库文件中
        fs.copyFileSync(resFile.fd, file.fd);
        fs.closeSync(file.fd);
        fs.closeSync(resFile.fd);
      }
      promptAction.showToast({
        message: '已保存至相册',
        duration: 2500
      });
    }
    catch (err) {
      console.error("error is "+ JSON.stringify(err))
      promptAction.showToast({
        message: '保存失败',
        duration: 2000
      });
    }
  }
  
  async  imageWriteAlbumExample2(fileUri:string) {
    console.info('createImageAssetRequestDemo:' + fileUri);
    let context = getContext(this);
    try {
      // 需要确保fileUri对应的资源存在
      let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
      let assetChangeRequest: photoAccessHelper.MediaAssetChangeRequest = photoAccessHelper.MediaAssetChangeRequest.createImageAssetRequest(context, fileUri);
      await phAccessHelper.applyChanges(assetChangeRequest);
      console.info('apply createVideoAssetRequest successfully');
      promptAction.showToast({
        message: '已保存至相册',
        duration: 2500
      });
    } catch (err) {
      console.error(`createVideoAssetRequestDemo failed with error: ${err.code}, ${err.message}`);
      promptAction.showToast({
        message: '保存失败',
        duration: 2000
      });
    }
  }

  async  imageWriteFileManager(fileUri:string) {
    let saveUris: Array<string> = [];
    let titleStr = 'testImage'+ new Date().getTime() + '.jpg'
    try {
      const photoSaveOptions = new picker.PhotoSaveOptions(); // 创建文件管理器保存选项实例
      photoSaveOptions.newFileNames = [titleStr]; // 保存文件名(可选),方括号里的文件名自定义,每次不能重复,设备里已有这个文件的话,名字就需要改个不一样的,不然接口会报错
      const photoViewPicker = new picker.PhotoViewPicker();
      try {
        let photoSaveResult = await photoViewPicker.save(photoSaveOptions);
        if (photoSaveResult != undefined) {
          saveUris = photoSaveResult;
          console.info('photoViewPicker.save to file succeed and uris are:' + photoSaveResult);
          let photoSelect = fs.openSync(fileUri, fs.OpenMode.READ_ONLY);
          let photoSave = fs.openSync(saveUris[0], fs.OpenMode.WRITE_ONLY);
          fs.copyFileSync(photoSelect.fd, photoSave.fd);
          fs.close(photoSelect);
          fs.close(photoSave);
          promptAction.showToast({
            message: '已保存至文件管理器',
            duration: 2500
          });
        }
      } catch (error) {
        let err: BusinessError = error as BusinessError;
        console.error(`[picker] Invoke photoViewPicker.save failed, code is ${err.code}, message is ${err.message}`);
        promptAction.showToast({
          message: '保存失败',
          duration: 2000
        });
      }
    } catch (error) {
      let err: BusinessError = error as BusinessError;
      console.info("[picker] photoViewPickerSave error = " + JSON.stringify(err));
    }
  }
}
分享
微博
QQ
微信
回复
2024-12-25 19:38:06
相关问题
HarmonyOS 实现保存图片相册
289浏览 • 1回复 待解决
HarmonyOS 保存图片相册问题
539浏览 • 1回复 待解决
HarmonyOS 保存图片本地相册
200浏览 • 1回复 待解决
HarmonyOS 保存图片系统相册
219浏览 • 1回复 待解决
HarmonyOS 截图保存图片相册
217浏览 • 1回复 待解决
如何保存网络图片相册
1034浏览 • 1回复 待解决
HarmonyOS h5如何实现保存图片相册
279浏览 • 1回复 待解决
HarmonyOS 保存图片相册权限问题
495浏览 • 1回复 待解决
如何保存本地图片相册
1378浏览 • 1回复 待解决
怎么实现保存网络图片相册功能?
765浏览 • 1回复 待解决
求大佬告知如何保存图片相册
1511浏览 • 1回复 待解决
HarmonyOS保存图片系统相册问题咨询
927浏览 • 1回复 待解决
HarmonyOS 图片保存相册
32浏览 • 1回复 待解决
HarmonyOS图片保存相册问题
724浏览 • 1回复 待解决
如何保存一张PNG图片相册
2143浏览 • 1回复 待解决
鸿蒙开发保存页面相册
6769浏览 • 1回复 待解决
HarmonyOS 图片保存相册报错
319浏览 • 1回复 待解决