HarmonyOS鸿蒙Next卡片开发中GIF图片怎么渲染?

HarmonyOS鸿蒙Next卡片开发中GIF图片怎么渲染? 卡片开发中GIF图片怎么渲染? 网络gif图片通过formImages 传递到卡片内。

memory:// 资源怎么读取? 有没有大佬知道啊。使用 Image 加载传递的gif不是动图,使用 ImageKnifeComponent 不显示图片。ohos_gif-drawable 不知道 资源该怎么加载

12 回复

更多关于HarmonyOS鸿蒙Next卡片开发中GIF图片怎么渲染?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


我也是按着开发的,但是动图不知道怎么处理,

文档上明确了就是只会渲染一次,你可以用定时器反复改变那个图片的值 这样就是反复刷新,但是性能上不考虑,

通过formImages传递的网络GIF需先下载到沙箱路径:

import { fileUri } from '@kit.CoreFileKit';
import http from '@kit.NetworkKit';

// 下载并保存到沙箱
let tempPath = getContext().filesDir + '/temp.gif';
http.downloadFile(url, tempPath).then(() => {
  let uri = fileUri.getUriFromPath(tempPath); // 转换为应用可访问URI
  // 使用uri加载图片
});

memory://路径需通过沙箱文件系统访问:

import fs from '@kit.CoreFileKit';

let buffer = fs.readSync('memory://gif_data'); // 读取内存数据
let gifData = parseGIF(buffer); // 解析GIF二进制数据

关键怎么渲染,gif动画执行一次就不执行了,

还这个代码你确定,卡片中可以用吗? 哈哈哈,怎么感觉像大模型输出的,

gif能够渲染一次,但是在桌面经常会触发显示,memory://的使用你参考一下我这个方法

  1. 图片下载存储处理:
let downloadImageData = await this.downloadOnlineImage(event.appIcon, tempDir);
if (downloadImageData.fileName) {
  event.appIcon = downloadImageData.fileName;
}
  1. 在UI上的使用
Image(typeof item.appIcon === 'string' ? 'memory://' + item.appIcon : item.appIcon)
  .width(33)
  .aspectRatio(1)
  .padding(2)
  .borderRadius(16.5)
  .alt($r('app.media.icon_default_app_icon'))
  1. 重点操作:如果是在线图片下载后,直接读取文件的fd结合memory://来使用
imgMap[fileName] = imgFile.fd;
/**
 * 卡片类方法:下载图片
 * @param netFile 网络图片地址
 * @param tempDir 应用临时目录
 * @returns 返回图片临时文件路径、文件名以及图片映射信息;如果下载失败,则返回空字符串和空映射
 */
async function downloadOnlineImage(netFile: ResourceStr, tempDir: string): Promise<DownloadResult> {
  let fileName = 'file' + Date.now();
  let tmpFile = `${tempDir}/${fileName}`;
  let imgMap: Record<string, number> = {};
  let httpRequest = http.createHttp();
  let imgFile: fileIo.File | '' = ''; // 初始值设置为 ''
  try {
    let data = await httpRequest.request(netFile.toString());
    if (data?.responseCode === http.ResponseCode.OK) {
      try {
        console.log("下载成功")
        imgFile = fileIo.openSync(tmpFile, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
        imgMap[fileName] = imgFile.fd;
        // 优化:将返回的图片映射赋值给 formData.formImages
        this.formImages[fileName] = imgFile.fd;
        let writeLen: number = await fileIo.write(imgFile.fd, data.result as ArrayBuffer);
        LogUtil.i(Tag, "write data to file succeed and size is:" + writeLen,
          'ArkTSCard download complete: %{public}s', tmpFile)
        return { tmpFile, fileName, imgMap };
      } catch (err) {
        LogUtil.e(Tag, "write data to file failed with error message: ", err)
        return { tmpFile: '', fileName: '', imgMap: {} };
      } finally {

      }
    } else {
      LogUtil.e(Tag, `ArkTSCard download task failed`)
      return { tmpFile: '', fileName: '', imgMap: {} };
    }
  } catch (error) {
    let errMsg = JSON.stringify(error);
    LogUtil.e(Tag, `HTTP request failed: ${errMsg}`)
    return { tmpFile: '', fileName: '', imgMap: {} };
  } finally {
    httpRequest.destroy();
    /*      if (imgFile) {
            fileIo.closeSync(imgFile.fd);
          }*/
  }
}

memory://  资源怎么读取

为了性能,肯定是不能一直播放gif动图的,这个在Image组件中有说明

互动类型的卡片,可以看这个官方文档互动卡片概述-互动卡片开发-ArkTS卡片开发(推荐)-Form Kit(卡片开发服务)-应用框架 - 华为HarmonyOS开发者

又没其他方式,播放呢,

在HarmonyOS NEXT中,使用Image组件渲染GIF图片需通过PixelMap实现。步骤如下:

  1. 解码GIF:使用ImageSource创建源对象,设置格式为image/gif,调用createPixelMap()获取帧数据。
  2. 动态渲染:通过Image组件的pixelMap属性绑定解码后的帧数据,结合Animator组件控制帧切换逻辑。
  3. 资源管理:注意及时释放PixelMap对象防止内存泄漏。

关键代码示例:

let imageSource = image.createImageSource(/*gif路径*/);
imageSource.createPixelMap().then((pixelMap) => {
  this.pixelMap = pixelMap; // 绑定到Image组件
});

在HarmonyOS Next卡片开发中渲染GIF图片,可以尝试以下方案:

  1. 对于网络GIF图片:
  • 使用Image组件时,确保设置autoPlay(true)和fillMode(ImageFillMode.Cover)
  • 推荐使用ImageKnifeComponent,需要正确配置权限和网络访问
  1. memory://资源读取:
  • 需要通过FileIO或ResourceManager API将内存中的二进制数据转换为PixelMap
  • 示例代码:
let resource = resourceManager.getRawFileContent('memory://xxx.gif');
let imageSource = image.createImageSource(resource);
let pixelMap = await imageSource.createPixelMap();
  1. ohos_gif-drawable使用:
  • 需要先将GIF数据转换为ArrayBuffer
  • 示例代码:
let gifDrawable = new GifDrawable(arrayBuffer);
canvas.drawGif(gifDrawable, 0, 0);

注意:卡片对动态内容有严格限制,建议考虑使用帧动画替代GIF,或确保GIF时长不超过卡片刷新周期。

回到顶部