HarmonyOS 鸿蒙Next:uniapp转H5 API不支持,手动适配保存相册和文件解决方案

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

HarmonyOS 鸿蒙Next:uniapp转H5 API不支持,手动适配保存相册和文件解决方案 uniapp转H5再套web,API不支持,需要手动适配保存相册和保存文件,有没有好的解决方案

2 回复
Demo:

```javascript
import { image } from '[@kit](/user/kit).ImageKit';
import util from '[@ohos](/user/ohos).util';
import pickers from '[@ohos](/user/ohos).file.picker';
import systemDateTime from '[@ohos](/user/ohos).systemDateTime';
import fs from '[@ohos](/user/ohos).file.fs';
import { buffer, JSON } from '[@kit](/user/kit).ArkTS';
import photoAccessHelper from '[@ohos](/user/ohos).file.photoAccessHelper';

class imagetmp {
  codeImg: PixelMap | undefined = undefined

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

[@Entry](/user/Entry)
[@Component](/user/Component)
struct ImageDemo {
  [@State](/user/State) resultBase64Str: string = '';
  [@State](/user/State) getAlbum: string = '显示相册中的图片';
  [@State](/user/State) pixel: image.PixelMap | undefined = undefined;
  [@State](/user/State) albumPath: string = '';
  [@State](/user/State) photoSize: number = 0;
  private base64Str: string = '';
  private settings: RenderingContextSettings = new RenderingContextSettings(true)
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
  [@State](/user/State) pixelMap: PixelMap | undefined = undefined;

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

        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 imageData: ArrayBuffer = OutData.result as ArrayBuffer;
      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: image.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> {
    // 将原始图片base64字符串转变为通过base64字符串
    // const reg = new RegExp('data:image/\\w+;base64,')
    // const base64Str = base64.replace(reg, '')
    // 将通用base64字符串转变为arrayBuffer
    let base64Helper = new util.Base64Helper();
    let uint8Array = base64Helper.decodeSync(base64)
    let arrayBuffer = uint8Array.buffer
    // 将arrayBuffer转变为pixelMap
    let imageSource = image.createImageSource(arrayBuffer)
    let opts: image.DecodingOptions = { editable: false }
    // 注意:这里return的是Promise,因此使用时需要在业务侧拿到最终的PixelMap
    return imageSource.createPixelMap(opts);
  }
}

权限配置(module.json5):

"requestPermissions": [
      {
        "name": "ohos.permission.CAMERA",
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when": "inuse"
        },
        "reason": "$string:CAMERA"
      },
      {
        "name": "ohos.permission.READ_IMAGEVIDEO",
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when": "inuse"
        },
        "reason": "$string:CAMERA"
      },
      {
        "name": "ohos.permission.WRITE_IMAGEVIDEO",
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when": "inuse"
        },
        "reason": "$string:CAMERA"
      }
    ]

更多关于HarmonyOS 鸿蒙Next:uniapp转H5 API不支持,手动适配保存相册和文件解决方案的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


针对HarmonyOS鸿蒙Next平台上uniapp转H5 API不支持,手动适配保存相册和文件的问题,可以通过以下方案进行解决:

在HarmonyOS上,由于系统API与标准Web API存在差异,uniapp转H5后可能无法直接使用某些API,特别是涉及文件系统操作的API。为了手动适配保存相册和文件的功能,你可以考虑以下步骤:

  1. 使用HarmonyOS提供的文件系统API:HarmonyOS提供了专门的文件系统API,用于访问和修改设备上的文件。你可以通过调用这些API来实现文件的保存和读取操作。

  2. 调用相册访问权限:在HarmonyOS上,应用需要获取相册访问权限才能将图片保存到相册中。确保你的应用已经声明并获取了相应的权限。

  3. 实现文件转换和保存:如果你需要将文件保存为特定格式(如图片),你可能需要在保存前进行格式转换。HarmonyOS提供了相关的图像处理API,可以帮助你完成这一任务。

  4. 测试与调试:在HarmonyOS设备上测试你的应用,确保文件保存和相册访问功能正常工作。注意检查权限申请、文件路径和格式转换等方面的问题。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部