48ee025a创建于 3 天前历史提交

apng-drawable

Introduction

apng-drawable is fast and light weight Animated Portable Network Graphics(APNG) image decoder library.As a product adapted from apng-drawable, this library can run on OpenHarmony, reusing its APIs and features.

How to Install

   ohpm install @ohos/apng-drawable

For details about the OpenHarmony ohpm environment configuration, see OpenHarmony HAR.

How to Use

Import and use

import { ApngDrawable, AnimationCallback } from '@ohos/apng-drawable';

@Entry
@Component
struct Index {
 @State drawable: ApngDrawable | null = null;
 @State callbackText: string = '';
 ...
 
 build() {
   Column() {
     Row() {
       Text('ApngDrawable')
         .fontSize(20)
         .fontWeight(FontWeight.Bold)
         .fontColor(Color.White)
         .layoutWeight(1)
         .textAlign(TextAlign.Center)
     }
     .width('100%')
     .height(56)
     .backgroundColor(PRIMARY_COLOR)
     .padding({ left: 16, right: 16 })

     Column() {
       Text($r('app.string.image_1'))
         .fontSize(14)
         .fontWeight(FontWeight.Medium)
         .margin({ top: 16, bottom: 8, left: 16 })
         .width('100%')
         .textAlign(TextAlign.Start)

       Scroll() {
         Row() {
           this.createButton($r('app.string.load'), () => this.startLoad('test.png'));
           this.createButton($r('app.string.load_5x'), () => this.startLoad('test.png', 500, 500));
           this.createButton($r('app.string.load_10x'), () => this.startLoad('test.png', 1000, 1000));
           this.createButton($r('app.string.copy'), () => this.duplicate());
           this.createButton($r('app.string.remove'), () => this.removeView());
         }
         .padding({ left: 12, right: 12, top: 4, bottom: 4 })
       }
       .scrollable(ScrollDirection.Horizontal)
       .scrollBar(BarState.Off)
       .width('100%')
     }
     .layoutWeight(1)
     .width('100%')
     .backgroundColor('#FFFFFF')
     }
     .width('100%')
   .height('100%')
   .backgroundColor('#FFFFFF')
 }

 @Builder
 createButton(text: Resource, onClick: () => void): void {
   Button(text)
     .type(ButtonType.Normal)
     .backgroundColor('#E0E0E0')
     .fontColor('#000000')
     .fontSize(14)
     .fontWeight(FontWeight.Normal)
     .height(36)
     .padding({ left: 16, right: 16 })
     .margin({ right: 8 })
     .onClick(onClick)
 }
 ...
}

For details, see the implementation on the sample page of the open-source library.

Available APIs

Constants

Constant Value Description
LOOP_FOREVER 0 Loop indefinitely
LOOP_INTRINSIC -1 Use intrinsic loop count from APNG

Properties

Property Type Description
durationMillis number Total animation duration in milliseconds (readonly)
frameCount number Total number of frames in the animation (readonly)
frameDurations number[] Duration of each frame in milliseconds (readonly)
frameByteCount number Byte size of a single frame buffer (width × height × 4) (readonly)
allocationByteCount number Total memory allocation for all frames (readonly)
isRecycled boolean Whether the drawable has been recycled (readonly)
currentLoopIndex number Current loop iteration index (readonly)
currentFrameIndex number Current frame index (readonly)

Methods

Method Parameters Return Description
decode() buffer: ArrayBuffer, width?: number, height?: number ApngDrawable Decode APNG
isApng() buffer: ArrayBuffer boolean Check if it is APNG
start() - void Start playback
stop() - void Stop playback
isRunning() - boolean Check if animation is running
seekTo() positionMillis: number void Seek to position in ms
seekToFrame() loopIndex: number, frameIndex: number void Seek to frame by loop & frame index
getLoopCount() - number Get loop count
setLoopCount() count: number void Set loop count
- -1: Use intrinsic loop count from APNG file
- 0: Infinite loop (default)
- n > 0: Stop after looping n times
registerAnimationCallback() callback: AnimationCallback void Register animation callback
unregisterAnimationCallback() callback: AnimationCallback boolean Unregister animation callback
clearAnimationCallbacks() - void Clear all callbacks
copy() - ApngDrawable Copy ApngDrawable instance
recycle() - void Recycle resources
getCurrentFrame() - Promise<PixelMap | null> Get current frame PixelMap
exportAsBitmap() - Promise<PixelMap | null> Export current frame as Bitmap (PixelMap)
saveAsPng() filePath: string Promise<boolean> Save current frame as PNG file

Constraints

Verified on the following versions:

  • DevEco Studio NEXT Developer Beta3: (5.0.3.530), SDK: API12 (5.0.0.35(SP3))

Directory Structure

|---- ohos_apng-drawable  
|     |---- entry  # Sample Code Folder
|     |---- library  # apng-drawable Library Folder
|     |     |---- src
|     |     |     └── main  
|     |     |         |---- cpp  # C++ Native Code
|     |     |         |    |---- apng-drawable  # APNG Decoder Core
|     |     |         |    |---- thirdparty/libpng  # libpng Core Library
|     |     |         |    |---- CMakeLists.txt
|     |     |         |    └──   napi_init.cpp
|     |     |         └── ets  # ArkTS Code
|     |     |             |---- apng
|     |     |             |    |---- Apng.ets        # APNG Wrapper Class
|     |     |             |    |---- ApngDrawable.ets # Drawable Implementation
|     |     |             |---- types
|     |     |             |    |---- ApngTypes.ets   # Type Definitions
|     |     |---- Index.ets  # External APIs
|     |---- README.md  # Readme
|     |---- README_zh.md  # Readme

Compile & Generate .so Library

Run the script: ./prebuild.sh

Copy the compiled libpng folder to library/src/main/cpp/thirdparty in the project.

apng-drawable’s main features are implemented natively and exposed to ArkTS.

How to Contribute

If you find any problem when using the project, submit an issue or a PR.

License

This project is licensed under Apache License 2.0.