一、背景
在开发过程中,我们可能会遇到需要控制 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));// 获取所有帧的 PixelMaplet 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/cheinlu/HarmonyOS-groundhog-marble-system
最后:👏👏😊😊😊👍👍