HarmonyOS 保存图片时,如何获取目标图片的uri,或如何保存传入的图片?

由于无法申请WRITE_IMAGEVIDEO和READ_IMAGEVIDE权限,选择调用提供的API:showAssetsCreationDialog如何将需要保存的图片转为可识别的uri?使用:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-file-fileuri-V5#tostring10

获得uri:file://com.xxx.xxxx.ohoslib/https%3A//shot.image.video.qpic.cn/screen_shot/vid/r4100ata9is/93360_864_486_0.jpg,但使用此uri,拉起保存确认弹窗,点击保存后,相册中并未出现目标图片。是否uri不正确?或有无其他办法保存传入图片?

HarmonyOS
1天前
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
fox280

具体请参考demo:

import { http } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';
import util from '@ohos.util';
import { fileUri } from '@kit.CoreFileKit';
import fs, { ReadOptions } from '@ohos.file.fs';
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { promptAction } from '@kit.ArkUI';

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  url1: string = "xxxx";
  url2 : string =
    "xxxxx";
  build() {
    Column (){
      Column() {
        Text(this.url1)
        Button ("保存").onClick(()=>{
          this.downloadAndSave(this.url1, "jpg")
        })
      }.margin({top: 15, bottom :15})
      
      Column() {
        Text(this.url2)
        Button ("保存").onClick(()=>{
          this.downloadAndSave(this.url2, "png");
        })
      }.margin({top: 15, bottom :15})
      
    }.justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center)
    .height('100%')
    .width('100%')
  }

  downloadAndSave (url: string, type: string) {
    httpDownload(url, type).then((result: DownloadResult)=>{
      if (result.isSuccess) {
        promptAction.showToast({message : "下载成功" })
      } else {
        console.error("失败:" + result.msg);
        promptAction.showToast({message : "下载失败,请查看日志" })
      }
    })
  }
}

interface DownloadResult {
  isSuccess: boolean,
  msg: string
}

async function httpDownload (imgUrl: string, imgType: string) : Promise<DownloadResult> {
  return new Promise((resolve, reject) => {
    http.createHttp().request(imgUrl, async (error: BusinessError, data: http.HttpResponse) => {
      // 下载失败
      if (error) {
        return resolve({ isSuccess: false, msg : "下载失败"});
      }

      // 数据格式不正确
      if ((data.result instanceof ArrayBuffer) == false) {
        return resolve({ isSuccess: false, msg : "图片保存失败:数据流不支持"});
      }
      // 保存到Cache目录下

      let imageBuffer: ArrayBuffer = data.result as ArrayBuffer;
      const newFileName = util.generateRandomUUID() + "." + imgType;
      const newFilePath = getContext().cacheDir + "/" + newFileName;
      const newFileUri = fileUri.getUriFromPath(newFilePath);
      let file: fs.File = await fs.open(newFileUri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
      await fs.write(file.fd, imageBuffer);
      await fs.close(file);
      console.info("文件路径:" + newFileUri);
      saveImageToAsset(newFileUri, imgType).then(()=>{
        // 保存成功
        return resolve({ isSuccess: true, msg : "保存成功"});
      }).catch((error: Error)=> {
        // 保存失败
        return resolve({ isSuccess: false, msg : "保存失败:" + error.message });
      });
    });
  })
}

async function saveImageToAsset(uri: string, nameExtension : string) : Promise<void> {
  console.info('ShowAssetsCreationDialogDemo: ' + uri);
  try {
    let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(getContext());
    // 获取需要保存到媒体库的位于应用沙箱的图片/视频uri
    let srcFileUris: Array<string> = [uri];
    let photoCreationConfigs: Array<photoAccessHelper.PhotoCreationConfig> = [
      {
        title: 'test2', // 可选
        fileNameExtension: nameExtension,
        photoType: photoAccessHelper.PhotoType.IMAGE,
        // 可选,支持:普通图片、动态图片
        subtype: photoAccessHelper.PhotoSubtype.DEFAULT,
      }
    ];
    let desFileUris: Array<string> = await phAccessHelper.showAssetsCreationDialog(srcFileUris, photoCreationConfigs);
    console.info('showAssetsCreationDialog success, data is ' + desFileUris);
    if (desFileUris.length == 0) {
      // 用户拒绝保存
      throw(new Error("用户拒绝保存"))
    }
    await createAssetByIo(uri, desFileUris[0]);

    return Promise.resolve();
  } catch (err) {
    console.error('showAssetsCreationDialog failed, errCode is ' + err.code + ', errMsg is ' + err.message);
    return Promise.reject(err);
  }
}

let context = getContext(this);
const createAssetByIo = async (sourceFilePath: string, targetFilePath: string) => {
  try {
    console.log(`context.fileDir ===> ${context.filesDir}`)
    let srcFile: fs.File = fs.openSync(sourceFilePath, fs.OpenMode.READ_ONLY);
    let targetFile: fs.File = await fs.open(targetFilePath, fs.OpenMode.READ_WRITE);
    let bufSize = 14096;
    let readSize = 0;
    let buf = new ArrayBuffer(bufSize);
    let readOptions: ReadOptions= {
      offset: readSize,
      length: bufSize
    };
    let readLen = fs.readSync(srcFile.fd, buf, readOptions);
    while (readLen > 0) {
      readSize += readLen;
      fs.writeSync(targetFile.fd, buf, {length: readLen});
      readOptions.offset = readSize;
      readLen = fs.readSync(srcFile.fd, buf, readOptions);
    }
    fs.closeSync(srcFile);
    fs.closeSync(targetFile);
  } catch (error) {
    console.error(`createAssetByIo :: error , msg is ${error} `);
  }
}
分享
微博
QQ
微信
回复
1天前
相关问题
HarmonyOS 图片保存
214浏览 • 1回复 待解决
HarmonyOS 图片保存失败
14浏览 • 1回复 待解决
HarmonyOS 图片保存功能
169浏览 • 1回复 待解决
使用SaveButton保存图片方式
790浏览 • 1回复 待解决
HarmonyOS 组件生成图片保存
193浏览 • 1回复 待解决
HarmonyOS 图片保存到相册
15浏览 • 1回复 待解决
HarmonyOS savebutton使用影响图片保存
209浏览 • 1回复 待解决
如何保存网络图片到相册
1001浏览 • 1回复 待解决
HarmonyOS图片保存相册问题
707浏览 • 1回复 待解决
HarmonyOS 保存图片文件异常
487浏览 • 1回复 待解决
HarmonyOS 如何图片保存到相册
129浏览 • 1回复 待解决
获取网络图片保存到相册
1802浏览 • 1回复 待解决
ArkUI(eTS)如何实现本地图片保存
7318浏览 • 1回复 待解决
如何保存http网络图片到本地
280浏览 • 1回复 待解决
如何保存本地图片到相册中
1350浏览 • 1回复 待解决