HarmonyOS 鸿蒙Next mageUI组件加载网络图片成功后如何获取已下载图片的PixelMap

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

HarmonyOS 鸿蒙Next mageUI组件加载网络图片成功后如何获取已下载图片的PixelMap

咨询描述:ImageUI组件在加载网络图片并成功显示后,如何获取已经下载图片的 PixelMap?

工程机版本:NOH-AN00 3.0.0.25(SP39DEVC00E25R4P2log)

DevEco Studio版本:DevEco Studio 5.0.3.402

2 回复

您好,可以使用Image Kit模块相关接口获取图片的pixelMap。具体使用方式可参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/image-overview-V5

以下示例可以获取到图片的pixelmap以及保存

import image from '[@ohos](/user/ohos).multimedia.image';
import picker from '[@ohos](/user/ohos).file.picker';
import fs from '[@ohos](/user/ohos).file.fs';
import common from '[@ohos](/user/ohos).app.ability.common';
import mediaLibrary from '[@ohos](/user/ohos).multimedia.mediaLibrary';

// 打包 PixelMap 为 jpg 格式
async function packingPixelMap2Jpg(pixelMap: PixelMap): Promise<ArrayBuffer> {
   const imagePackerApi = image.createImagePacker();

   // 设置打包参数
   const packOpts: image.PackingOption = { format: "image/jpeg", quality: 98 };
   let imageBuffer: ArrayBuffer;

   try {
       // 图片压缩或重新打包
       imageBuffer = await imagePackerApi.packing(pixelMap, packOpts);
   } catch (err) {
       console.error(`Invoke packingPixelMap2Jpg failed, err: ${JSON.stringify(err)}`);
   }

   return imageBuffer;
}

async function getMediaUriByFilePickerSave(): Promise<string> {
   let mediaUri: string;

   try {
       const PhotoSaveOptions = new picker.PhotoSaveOptions();
       PhotoSaveOptions.newFileNames = [`IMG_${getTimeStringInYYMMDD_HHMMSS()}.jpg`];

       const photoPicker = new picker.PhotoViewPicker();
       const photoSaveResult = await photoPicker.save(PhotoSaveOptions);
       mediaUri = photoSaveResult[0];
   } catch (err) {
       console.error(`Invoke photoPicker.save failed, err: ${JSON.stringify(err)}`);
   }

   return mediaUri;
}

// 保存图片 ArrayBuffer 二进制数据至媒体库
async function saveArrayBuffer2MediaLibrary(context: common.Context, buffer: ArrayBuffer): Promise<void> {
   const media = mediaLibrary.getMediaLibrary(context);
   const DIR_IMAGE = mediaLibrary.DirectoryType.DIR_IMAGE;
   const mediaType = mediaLibrary.MediaType.IMAGE;

   try {
       const imagePath = await media.getPublicDirectory(DIR_IMAGE);
       const imageFileAsset = await media.createAsset(mediaType, `IMG_${getTimeStringInYYMMDD_HHMMSS()}.jpg`, imagePath);
       const imageFileAssetFd = await imageFileAsset.open('rw');

       // 将二进制数据写入创建的图片文件
       fs.writeSync(imageFileAssetFd, buffer);
       await imageFileAsset.close(imageFileAssetFd);
   } catch (err) {
       console.error(`Invoke saveArrayBuffer2MediaLibrary failed, err: ${JSON.stringify(err)}`);
   }
}

function saveArrayBuffer2File(buffer: ArrayBuffer, uri: string) {
   try {
       const file = fs.openSync(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
       fs.writeSync(file.fd, buffer);
       fs.closeSync(file);
   } catch (err) {
       console.error(`Invoke copyFile failed, err: ${JSON.stringify(err)}`);
   }
}

// 获取两位字符串
function get2DigitStr(num: number): string {
   let numStr = num.toString();
   const numStrLen = numStr.length;

   if (numStrLen === 1) {
       numStr = `0${numStr}`;
   } else {
       numStr = numStr.substring(numStrLen - 2, numStrLen);
   }

   return numStr;
}

// 获取 'YYMMDD_HHMMSS' 格式的时间戳
function getTimeStringInYYMMDD_HHMMSS(): string {
   const curDate = new Date();
   let year = curDate.getFullYear();
   let mouth = get2DigitStr(curDate.getMonth() + 1);
   let date = get2DigitStr(curDate.getDate());
   let hours = get2DigitStr(curDate.getHours());
   let minutes = get2DigitStr(curDate.getMinutes());
   let seconds = get2DigitStr(curDate.getSeconds());

   return `${year}${mouth}${date}_${hours}${minutes}${seconds}`;
}

// 通过 uri 解析图片为 PixelMap
export async function getPixelMapByImageUri(uri: string): Promise<image.PixelMap> {
   const imageSource = image.createImageSource(uri);
   const decodingOptions: image.DecodingOptions = {
       editable: true,
       desiredPixelFormat: 3,
   };

   let pixelMap: PixelMap;

   try {
       pixelMap = await imageSource.createPixelMap(decodingOptions);
   } catch (err) {
       console.error(`Invoke imageSource.createPixelMap failed, err: ${JSON.stringify(err)}`);
   }

   return pixelMap;
}

export async function savePixelMap2MediaLibraryByFilePicker(pixelMap: PixelMap) {
   try {
       const imageBuffer = await packingPixelMap2Jpg(pixelMap);
       const mediaUri = await getMediaUriByFilePickerSave();

       if (mediaUri && imageBuffer.byteLength) {
           const imageUri = `${mediaUri}/IMG_${getTimeStringInYYMMDD_HHMMSS()}.jpg`;
           saveArrayBuffer2File(imageBuffer, imageUri);
           console.info(`Invoke savePixelMap2MediaLibrary succeed`);
       }
   } catch (err) {
       console.error(`Invoke savePixelMap2MediaLibrary failed, err: ${JSON.stringify(err)}`);
   }
}

// 保存 PixelMap 至媒体库
export async function savePixelMap2MediaLibrary(pixelMap: PixelMap, context: common.Context): Promise<void> {
   try {
       const imageBuffer = await packingPixelMap2Jpg(pixelMap);

       if (imageBuffer.byteLength) {
           saveArrayBuffer2MediaLibrary(context, imageBuffer);
           console.info(`Invoke savePixelMap2MediaLibrary succeed`);
       } else {
           console.error(`Invoke savePixelMap2MediaLibrary failed, err: image is null`);
       }
   } catch (err) {
       console.error(`Invoke savePixelMap2MediaLibrary failed, err: ${JSON.stringify(err)}`);
   }
}

在HarmonyOS鸿蒙Next中,当mageUI组件成功加载网络图片后,若需获取已下载图片的PixelMap,可遵循以下步骤:

  1. 确保缓存机制:首先,应用需具备图片缓存机制,以存储下载的图片。这可通过内存缓存和磁盘缓存实现。
  2. 检查并加载缓存:在尝试获取PixelMap前,检查本地缓存中是否存在该图片。若存在,使用ImageDecoder类解码缓存中的图片文件,并转换为PixelMap对象。
  3. 处理异常:在加载和转换过程中,应处理可能发生的异常,如文件不存在或解码失败等。
  4. 使用PixelMap:成功获取PixelMap后,可将其用于Image组件的显示或其他图像处理任务。

示例代码片段(假设已有缓存路径):

String cachePath = "path/to/cached/image";
ImageDecoder decoder = ImageDecoder.createDecoder(this, Uri.parse(cachePath));
decoder.decodeToBitmap(new DecodeToBitmapCallback() {
    @Override
    public void onSuccess(Bitmap bitmap) {
        PixelMap pixelMap = PixelMap.create(bitmap);
        // 使用pixelMap
    }

    @Override
    public void onError(ImageDecoder.ErrorResult errorResult) {
        // 处理错误
    }
});

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

回到顶部