HarmonyOS鸿蒙Next中web保存相册或文件到本地的实现方案

HarmonyOS鸿蒙Next中web保存相册或文件到本地的实现方案 uniapp转H5再套web,API不支持,需要手动适配保存相册和保存文件,有没有好的解决方案 比如API:uni.saveFile,保存文件到本地。

3 回复

请参考以下:

import { image } from '@kit.ImageKit';
import util from '@ohos.util';
import pickers from '@ohos.file.picker';
import systemDateTime from '@ohos.systemDateTime';
import fs from '@ohos.file.fs';
import { buffer, JSON } from '@kit.ArkTS';
import photoAccessHelper from '@ohos.file.photoAccessHelper';

class imagetmp {
  codeImg: PixelMap | undefined = undefined;

  set(val: PixelMap) {
    this.codeImg = val;
    console.log('PixelMap=========' + val);
  }
}

@Entry
@Component
struct ImageDemo {
  @State resultBase64Str: string = '';
  @State getAlbum: string = '显示相册中的图片';
  @State pixel: image.PixelMap | undefined = undefined;
  @State albumPath: string = '';
  @State photoSize: number = 0;

  private base64Str: string = '';
  private settings: RenderingContextSettings = new RenderingContextSettings(true);
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
  @State pixelMap: PixelMap | undefined = undefined;

  build() {
    Scroll() {
      Column() {
        Canvas(this.context)
          .width('100%')
          .height('50%')
          .backgroundColor('#ffff00')
          .onReady(() => {});

        Image(this.pixelMap).width(200).height(200);

        Button('保存图片')
          .onClick(() => {
            this.save();
          });

        Button('获取图片')
          .onClick(async () => {
            await this.getPictureFromAlbum();
          });

        Image('https://dev.yoohoor.com:17011/v2/auth/code?uuid=1111222')
          .width('100%')
          .height('20%');
      }
    }
  }

  async getPictureFromAlbum() { // 拉起相册,选择图片
    let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
    PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
    PhotoSelectOptions.maxSelectNumber = 1;

    let photoPicker = new photoAccessHelper.PhotoViewPicker();
    let photoSelectResult: photoAccessHelper.PhotoSelectResult = await photoPicker.select(PhotoSelectOptions);

    this.albumPath = photoSelectResult.photoUris[0];
    console.info('albumPath: ' + this.albumPath); // 读取图片为buffer

    const file = fs.openSync(this.albumPath, fs.OpenMode.READ_WRITE);
    this.photoSize = fs.statSync(file.fd).size;
    console.info('Photo Size: ' + this.photoSize);

    let buffer1 = new ArrayBuffer(this.photoSize);
    fs.readSync(file.fd, buffer1);

    this.base64Str = buffer.from(buffer1).toString('base64')
    let resultBase64Str = "data:image/png;base64," + this.base64Str;

    console.log('base64Str---', this.base64Str)
    this.resultBase64Str = resultBase64Str;
    fs.closeSync(file); // 解码成PixelMap

    const imageSource = image.createImageSource(buffer1);
    console.log('imageSource: ' + JSON.stringify(imageSource));

    let blob = new buffer.Blob([buffer1])
    console.log('blob---', JSON.stringify(blob));
  }

  setWidth() {
    const img: Uint8Array = getContext(this).resourceManager.getRawFileContentSync('ic_banner01.png');

    const imageSource: image.ImageSource = image.createImageSource(img.buffer);

    const PixelMap: image.PixelMap = imageSource.createPixelMapSync()
    PixelMap.scale(1.2, 1.2)

    const images = new ImageBitmap(PixelMap);

    const patter = this.context.createPattern(images, 'repeat')

    if (patter) {
      this.context.fillStyle = patter
    }

    this.context.fillRect(50, 50, 50, 50)
  }

  private async blobToImg(buffer: ArrayBuffer) {
    try {
      console.log('blobToImg===============' + buffer.toString())

      let imageSource: image.ImageSource = image.createImageSource(buffer);
      imageSource.getImageInfo().then(data => {
        console.log('imageSource2===============' + data)
      })

      console.log('imageSource===============' + imageSource.getImageInfo())

      class tmp {
        height: number = 100
        width: number = 100
      }

      let si: tmp = new tmp()

      let options: Record<string, number | boolean | tmp> = {
        'alphaType': 2, // 透明度
        'editable': true, // 是否可编辑
        'pixelFormat': 4, // 像素格式
        'scaleMode': 1, // 缩略值
        'size': { height: 760, width: 1440 }
      } // 创建图片大小

      console.log('options=====', JSON.stringify(options));

      let json = JSON.stringify(options);
      let test: Record<string, number | boolean | tmp> = JSON.parse(json) as Record<string, number | boolean | tmp>;

      imageSource.createPixelMap(test).then(pixelMap => {
        this.pixelMap = pixelMap;
        let im = new imagetmp()
        im.set(pixelMap)
      })
    } catch (err) {
      console.error(err)
    }
  }

  async save() {
    let pixelMap = await this.base64ToPixelMap1(this.base64Str)

    let arrayBuffer = new ArrayBuffer(3072 * 1024);
    pixelMap.readPixelsToBufferSync(arrayBuffer);

    let photoSaveOptions = new pickers.PhotoSaveOptions();

    let name = systemDateTime.getTime(true) + 'test.png';
    photoSaveOptions.newFileNames = [name];

    let photoPicker = new pickers.PhotoViewPicker(getContext(this));

    let photoSaveResult = await photoPicker.save(photoSaveOptions);

    console.log('photoSaveResult---', JSON.stringify(photoSaveResult))

    if (photoSaveResult.length == 0) {
      console.log('shibai--')
      return
    }

    let file = fs.openSync(photoSaveResult[0], fs.OpenMode.READ_WRITE);
    await fs.write(file.fd, arrayBuffer);
    fs.closeSync(file);
  }

  base64ToPixelMap1(base64: string): Promise<image.PixelMap> {
    let base64Helper = new util.Base64Helper();
    let uint8Array = base64Helper.decodeSync(base64)
    let arrayBuffer = uint8Array.buffer

    let imageSource = image.createImageSource(arrayBuffer)
    let opts: image.DecodingOptions = { editable: false }

    return imageSource.createPixelMap(opts);
  }
}

更多关于HarmonyOS鸿蒙Next中web保存相册或文件到本地的实现方案的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,实现Web保存相册或文件到本地的方案主要依赖于鸿蒙的分布式文件系统和Web组件能力。首先,通过Web组件的WebView加载网页内容,当用户在网页上触发保存操作时,可以通过JavaScript与鸿蒙的Native层进行交互。具体实现步骤如下:

  1. Web端触发保存操作:在Web页面中,通过JavaScript调用保存文件或图片的请求,可以使用window.postMessageWebViewevaluateJavascript方法将保存请求传递给鸿蒙应用。

  2. Native层接收请求:在鸿蒙应用的Native层,通过WebViewsetWebMessageListener方法监听来自Web端的保存请求。接收到请求后,解析出需要保存的文件或图片的URL或数据。

  3. 下载文件或图片:使用鸿蒙的ohos.net.http模块发起网络请求,下载文件或图片数据。下载完成后,将数据保存到本地文件系统中。

  4. 保存到相册或本地文件系统:对于图片文件,可以使用ohos.media.image模块将图片数据保存到相册;对于其他文件,可以使用ohos.file.fs模块将文件保存到指定的本地目录。

  5. 返回结果给Web端:保存完成后,通过WebViewpostMessage方法将保存结果返回给Web端,Web端根据结果进行相应的提示或处理。

通过以上步骤,可以在HarmonyOS鸿蒙Next中实现Web保存相册或文件到本地的功能。

在HarmonyOS鸿蒙Next中,保存Web资源如相册或文件到本地可以通过FilePickerFileIO模块实现。首先,使用FilePicker让用户选择保存位置,然后通过FileIO将Web资源写入指定路径。对于图片,可以先通过Image组件加载,再转换为Blob对象后保存。对于文件,可以直接下载并保存。代码示例如下:

import filePicker from '@ohos.filepicker';
import fileIO from '@ohos.fileio';

async function saveFileToLocal(url, fileName) {
    const filePath = await filePicker.pickFile({ fileName });
    const response = await fetch(url);
    const blob = await response.blob();
    await fileIO.write(filePath, blob);
}

确保应用已申请ohos.permission.WRITE_MEDIA权限。

回到顶部