当前位置: 首页 > news >正文

【HarmonyOS NEXT】控制 WebP 格式动图播放次数的实现方案

一、背景

在开发过程中,我们可能会遇到需要控制 WebP 格式动态图播放次数的需求。例如,某些场景下只需要动图播放一次,而不是循环播放。然而,使用原生组件(如 Image 或 ImageAnimator)时,WebP 动图会被当作普通图片处理,无法直接控制播放次数。本文将介绍两种解决方案:使用官方原生 API ImageAnimator 组件和使用第三方插件 ImageKnife

二、实现方式

2.1 使用官方原生 API - ImageAnimator 组件

2.2 使用第三方插件 - ImageKnife

三、使用 ImageAnimator 组件实现

官方文档指引👉:文档中心

3.1 解决思路

ImageAnimator 组件默认将 WebP 动图作为普通图片处理,无法直接控制播放次数。为了实现播放次数的控制,我们需要将 WebP 动图解析为多帧图片,然后将这些帧作为 ImageAnimator 的输入,从而实现对播放次数的精确控制。

3.2 示例代码

以下是使用 ImageAnimator 组件实现 WebP 动图播放一次的核心代码:

import { image } from '@kit.ImageKit';

@Entry
@Component
struct ImageAnimatorExample {
  @State state: AnimationStatus = AnimationStatus.Initial; // 控制动画状态
  imageFrames: Array<ImageFrameInfo> = []; // 存储解析后的帧信息
  isSelected: boolean = false; // 控制点击状态

  async aboutToAppear() {
    // 解析 WebP 动图,获取帧信息
    this.imageFrames = await this.getImageFrameInfoFromMedia($r('app.media.duck'));
  }

  build() {
    Column({ space: 10 }) {
      // ImageAnimator 组件
      ImageAnimator()
        .images(this.imageFrames) // 设置帧信息
        .state(this.state) // 设置动画状态
        .iterations(1) // 设置播放次数为 1
        .width(400)
        .height(400)
        .margin({ top: 100 })
        .onClick(() => {
          // 点击图片,开始播放动画
          this.isSelected = true;
          this.state = AnimationStatus.Running;
        });

      // 重置按钮
      Button('Reset')
        .onClick(() => {
          // 点击按钮,停止动画并重置状态
          this.isSelected = false;
          this.state = AnimationStatus.Stopped;
        });
    }
    .width('100%')
    .height('100%');
  }

  // 解析 WebP 动图,获取帧信息
  private async getImageFrameInfoFromMedia(resource: Resource) {
    // 获取 WebP 文件的二进制数据
    let unit8Array = await getContext(this)?.resourceManager?.getMediaContent({
      bundleName: resource.bundleName,
      moduleName: resource.moduleName,
      id: resource.id,
    });

    // 创建 ImageSource 对象
    let imageSource = image.createImageSource(unit8Array.buffer.slice(0, unit8Array.buffer.byteLength));

    // 获取所有帧的 PixelMap
    let createPixelMap: Array<image.PixelMap> = await imageSource.createPixelMapList({
      desiredPixelFormat: image.PixelMapFormat.RGBA_8888,
    });

    // 获取每帧的延迟时间
    let delayList = await imageSource.getDelayTimeList();
    await imageSource.release();

    // 构建帧信息数组
    let imageFrameInfoArray: Array<ImageFrameInfo> = [];
    for (let i = 0; i < createPixelMap.length; i++) {
      imageFrameInfoArray.push({
        src: createPixelMap[i],
        duration: delayList[i],
      });
    }

    return imageFrameInfoArray;
  }
}

3.3 实现效果

  • 点击“Reset”按钮后,动画停止并重置状态展示图片。

  • 点击图片后,动图开始播放,且只播放一次。

图2

四、使用第三方插件 ImageKnife

4.1 解决思路

ImageKnife 是一个功能强大的第三方插件,支持对动图的精细控制,包括播放次数、播放状态等。通过 ImageKnife,我们可以更简单地实现 WebP 动图的播放控制。

4.2 三方库介绍及安装

4.2.1 简介:

这是专门为OpenHarmony打造的一款图像加载缓存库,致力于更高效、更轻便、更简单

entry/src/main/ets/pages/ImageAnimatorPage.ets · OpenHarmony-TPC/ImageKnife - Gitee.com

4.2.2 安装:

ohpm i @ohos/imageknife

4.3 示例代码

以下是使用 ImageKnife 实现 WebP 动图播放的核心代码:

import { AnimatorOption, ImageKnifeAnimatorComponent } from '@ohos/imageknife';

@Entry
@Component
struct ImageAnimatorExample {
  @State animatorOption: AnimatorOption = {
    state: AnimationStatus.Running, // 动画状态
    iterations: 3, // 播放次数
  };

  build() {
    Column() {
      // ImageKnifeAnimatorComponent 组件
      ImageKnifeAnimatorComponent({
        imageKnifeOption: {
          loadSrc: $r('app.media.duck'), // 加载 WebP 动图
        },
        animatorOption: this.animatorOption, // 设置动画选项
      })
        .width(300)
        .height(300)
        .backgroundColor(Color.Orange)
        .margin({ top: 30 });
    }
    .width('100%')
    .height('100%');
  }
}

4.4 实现效果

  • 动图自动开始播放,控制播放3次。

  • 通过 animatorOption 可以灵活控制播放次数和状态。

图1

🚀🚀🚀  踩坑不易,还希望各位大佬支持一下

📃 鸿蒙土拨鼠充电开源项目:

✍GitHub开源项目地址👉:https://github.com/cheinlu/groundhog-charging-system

📃 鸿蒙土拨鼠大理石开源项目

✍GitHub开源项目地址👉https://github.com/lusson-luo/HarmonyOS-groundhog-marble-system

最后:👏👏😊😊😊👍👍  

相关文章:

  • 【Prometheus】prometheus服务发现与relabel原理解析与应用实战
  • 如何用 Python 进行机器学习
  • python学习七
  • linux上搭建Lago并部署
  • word转换为pdf后图片失真解决办法、高质量PDF转换方法
  • C语言32个关键字
  • 面试【进阶】 —— 说下csr、ssr、ssg 的区别?
  • 【MySQL 的数据目录】
  • Spring Cloud Alibaba与Spring Boot、Spring Cloud版本对应关系
  • 【AIDevops】Deepseek驱动无界面自动化运维与分布式脚本系统,初探运维革命之路
  • 进程通信——信号
  • ESP 32控制无刷电机2
  • 【前端进阶】10 掌握前端框架模板引擎的实现原理
  • SpringBoot返回文件让前端下载的几种方式
  • CISP-PTE:kali常用命令
  • 用大白话解释搜索引擎Elasticsearch是什么,有什么用,怎么用
  • 软件测试丨Native应用性能分析与优化指南
  • 鹏信科技入选2024年网络安全技术应用典型案例项目名单
  • 【Pandas】pandas Series ffill
  • LeapVAD:通过认知感知和 Dual-Process 思维实现自动驾驶的飞跃
  • 优秀的定制网站建设制作商/sem竞价是什么
  • 萍乡做网站的公司有哪些/北京seo公司网站
  • 带注册登录的网站模板/免费优化
  • 赌博游戏网站怎么自己做/网络广告网站
  • 网站开发做原型吗/seo运营是做什么的
  • 一个人可以做多少网站/百度网址大全 官网