HarmonyOS 鸿蒙Next中image.PixelMap如何缓存到沙箱环境并获取对应图片路径

HarmonyOS 鸿蒙Next中image.PixelMap如何缓存到沙箱环境并获取对应图片路径

let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = await phAccessHelper.getAssets(fetchOption);

// 得到uri对应的PhotoAsset对象,读取文件的部分信息
const photoAsset: photoAccessHelper.PhotoAsset = await fetchResult.getFirstObject();

// 获取视频缩略图
let sizeThumbnail: image.Size = { width: 720, height: 720 };
let pixelMap: image.PixelMap =  await photoAsset.getThumbnail(sizeThumbnail);

在获取视频缩略图时,返回的类型时image.PixelMap,我上传的时候统一要的是图片路径,如何把image.PixelMap缓存到沙箱环境并获取对应图片路径?


更多关于HarmonyOS 鸿蒙Next中image.PixelMap如何缓存到沙箱环境并获取对应图片路径的实战教程也可以访问 https://www.itying.com/category-93-b0.html

5 回复

【背景知识】

packToFile:通过指定编码参数,将ImageSource直接编码进文件。

【解决方案】

图片路径由开发者在保存过程中自定义,使用packToFile直接将文件编码为指定文件。

import { resourceManager } from '@kit.LocalizationKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { image } from '@kit.ImageKit';
import { fileIo, fileUri } from '@kit.CoreFileKit';

@Entry
@Component
struct SavePixelMapToCache {
  @State pixel: image.PixelMap | undefined = undefined;
  @State photoSize: number = 0;
  private context: Context = this.getUIContext().getHostContext()!;

  async aboutToAppear() {
    const resourceMgr: resourceManager.ResourceManager = this.context.resourceManager;
    const fileData: Uint8Array = await resourceMgr.getRawFileContent('ScreenShot.PNG');
    let buffer = new Uint8Array(fileData).buffer as object as ArrayBuffer;
    let imageResource = image.createImageSource(buffer);
    let opts: image.DecodingOptions = { editable: true };
    this.pixel = await imageResource.createPixelMap(opts);
  }

  async savePixelMapToCache() {
    let uri = fileUri.getUriFromPath(this.getUIContext().getHostContext()?.cacheDir + '/filename.png');
    console.log(this.getUIContext().getHostContext()?.cacheDir + '/filename.png') // 保存路径
    let file = await fileIo.open(uri, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
    let imagePackerApi = image.createImagePacker();
    let packOpts: image.PackingOption = { format: 'image/png', quality: 98 };
    imagePackerApi.packToFile(this.pixel, file.fd, packOpts, (err: BusinessError) => {
      if (err) {
        console.error(`Failed to pack the image to file.code ${err.code},message is ${err.message}`);
      } else {
        console.info('Succeeded in packing the image to file.');
        imagePackerApi.release((err: BusinessError) => {
          if (err) {
            console.error(`Failed to release the image source instance.code ${err.code},message is ${err.message}`);
          } else {
            console.info('Succeeded in releasing the image source instance.');
            fileIo.close(file.fd);
          }
        })
        this.getUIContext().getPromptAction().showToast({ message: '已保存至沙箱!' });
      }
    })
  }

  build() {
    Row() {
      Column() {
        Image(this.pixel)
          .objectFit(ImageFit.None)
          .height('30%')
        Button('保存到沙箱')
          .onClick(() => {
            this.savePixelMapToCache();
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

更多关于HarmonyOS 鸿蒙Next中image.PixelMap如何缓存到沙箱环境并获取对应图片路径的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


10-29 17:12:21.204   6382-6382     A03d00/JSAPP                    com.examp…et_daily  I     VideoCompressor constructor

10-29 17:12:21.205   6382-6382     A03d00/JSAPP                    com.examp…et_daily  I     quality:2–videoCompressor outPutFilePath:/data/storage/el2/base/haps/entry/files/1761729141205.mp4

10-29 17:12:21.253   6382-6382     A03d00/JSAPP                    com.examp…et_daily  I     videoCompressor inputFile fd:96

10-29 17:12:21.254   6382-6382     A03200/videoCompressor          com.examp…et_daily  E     inputSize:3049065

10-29 17:12:21.254   6382-6382     A03200/videoCompressor          com.examp…et_daily  E     outputPath:/data/storage/el2/base/haps/entry/files/1761729141205.mp4

10-29 17:12:21.318   6382-6411     A03200/videoCompressor          com.examp…et_daily  E     demuxer:audioMime:audio/mp4a-latm–audioBitrate:130530–aacIsADTS:1–audioSampleFormat:9–audioSampleRate:44100–audioChannelCount2–audioTrackId:0

10-29 17:12:21.318   6382-6411     A03200/videoCompressor          com.examp…et_daily  E     demuxer:videoMime:video/avc–width:1280–height:720–frameRate:30.000000–bitrate2592644–videoTrackId:1

10-29 17:12:21.318   6382-6411     A03200/videoCompressor          com.examp…et_daily  E     CreateDemuxer end

10-29 17:12:21.318   6382-6411     A03200/videoCompressor          com.examp…et_daily  E     CreateMutex start

10-29 17:12:21.319   6382-6411     A03200/videoCompressor          com.examp…et_daily  E     muxer:audioMime:audio/mp4a-latm–audioSampleRate:44100–audioChannelCount:2–audioBitrate:130530

10-29 17:12:21.319   6382-6411     A03200/videoCompressor          com.examp…et_daily  E     muxer:videoMime:video/avc–videoWidth:1280–videoHeight:720

10-29 17:12:21.321   6382-6411     A03200/videoCompressor          com.examp…et_daily  E     CreateMutex end

10-29 17:12:21.321   6382-6411     A03200/videoCompressor          com.examp…et_daily  E     CreateVideoEncode start CreateVideoEncoder

10-29 17:12:21.327   6382-6411     A03200/videoCompressor          com.examp…et_daily  E     CreateVideoEncoder error

10-29 17:12:21.327   6382-6411     A03200/videoCompressor          com.examp…et_daily  E     CreateVideoEncode error

10-29 17:12:21.330   6382-6382     A03200/videoCompressor          com.examp…et_daily  E     delete outputFile

10-29 17:12:21.330   6382-6382     A03200/videoCompressor          com.examp…et_daily  E     callback outputPath:/data/storage/el2/base/haps/entry/files/1761729141205.mp4

10-29 17:12:21.333   6382-6382     A0ff00/[PetDaily]               com.examp…et_daily  I     [CompressUtil], videoCompressor code:-1 --error message:CreateVideoEncode error

使用视频压缩插件压缩视频时,报了上面的错,换了好几个视频都不行,到底是什么原因?

@ohos/videocompressor

尊敬的开发者,您好。发现您已经重新提单,请跟踪新帖子处理进展。

在HarmonyOS Next中,通过image.PixelMap的getPixelMapBytes()方法获取图像字节数据,使用fs模块将字节数组写入沙箱路径。具体步骤:调用fs.createStream()创建文件流,通过stream.write()写入PixelMap数据,最后使用fs.access()验证文件路径。沙箱路径格式为context.filesDir + '/filename',可直接用于图片组件加载。

在HarmonyOS Next中,可以通过以下步骤将PixelMap缓存到沙箱并获取图片路径:

  1. 使用imagePacker将PixelMap编码为图片数据:
import image from '@ohos.multimedia.image';
import fs from '@ohos.file.fs';

// 创建ImagePacker实例
let imagePackerApi = image.createImagePacker();

// 将PixelMap编码为ArrayBuffer
let packingOptions: image.PackingOption = { format: "image/jpeg", quality: 98 };
let arrayBuffer: ArrayBuffer = await imagePackerApi.packing(pixelMap, packingOptions);
  1. 将ArrayBuffer写入沙箱文件:
// 沙箱路径
let cacheDir = getContext().cacheDir;
let filePath = cacheDir + '/thumbnail.jpg';

// 写入文件
let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
fs.writeSync(file.fd, arrayBuffer);
fs.closeSync(file.fd);
  1. 获取文件路径用于上传:
// 现在可以使用filePath作为图片路径
console.log('缩略图路径:', filePath);

完整示例:

async function savePixelMapToCache(pixelMap: image.PixelMap): Promise<string> {
  let imagePacker = image.createImagePacker();
  let options: image.PackingOption = { format: "image/jpeg", quality: 95 };
  let arrayBuffer = await imagePacker.packing(pixelMap, options);
  
  let cacheDir = getContext().cacheDir;
  let filePath = `${cacheDir}/thumbnail_${Date.now()}.jpg`;
  
  let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
  fs.writeSync(file.fd, arrayBuffer);
  fs.closeSync(file.fd);
  
  return filePath;
}

这样就可以将PixelMap保存为沙箱中的图片文件并获取其路径用于上传操作。

回到顶部