SimpleGif,一款使用方法类似Glide但更省cpu、memory的Android ndk gif解码库,cmake方式,android studio项目

9 篇文章 0 订阅
5 篇文章 0 订阅

Gif文件是由多张静态图片组合而成,每张图片都有自己的显示时间,屏幕通过连续显示这些图片,以达到动态图的目的,由于这些特性,导致如果用java去解码,可能效率不是那么高,因为java能运行速度始终无法匹敌c/c++,所以用jni技术,通过c/c++代码解码gif文件,再将解析得到的单张图片以及对应的显示时间返回到java层,再呈现到view上是比较好的方式。
我通过学习github上一些开源代码,制作了一个这样的c++代码库(使用方式类似Glide只需要一行代码),可以实现gif的解码,还可以制作gif动态图,基于Android Studio项目架构,使用cmake方式编译,地址:
https://github.com/yylyingy/SimpleGif
SimpleGif与Glide性能对比图:
Glide cpu and memory usage:
Glide
SimpleGif cpu and memory usage:
SimpleGif
上面两张图显示了SimpleGif与Glide同时加载9张Gif时CPU占用率以及内存占用,可以看到SimpleGif在这两项性能上均占优,看到SimpleGif的性能如此优异,是不是迫不及待的想要使用了,接下来将介绍SimpleGif的用法以及Sample实例;
首先将上面链接的项目clone到本地,在项目中,module library属于android library,如果想要在你自己的项目中使用,可以通过Android Studio的Import module导入到你自己的项目中(需要配置ndk路径,以及安装了cmake);
library这个module采用的是cmake方式编译,通过配置library/CMakeLists.txt来指定需要编译的c/c++源文件,编译后的动态链接库name,以及需要用到的libraries等等,c/c++源文件列表:
源文件
CMakeLists.txt内容:

# Sets the minimum version of CMake required to build the native
# library. You should either keep the default value or only pass a
# value of 3.4.0 or lower.

cmake_minimum_required(VERSION 3.4.1)
#add_compile_options(-std=c++03)
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds it for you.
# Gradle automatically packages shared libraries with your APK.

include_directories(D:/Android/WorkSpaseForAS/TestLibjpeg/app/libs)
add_library( # Sets the name of the library.
             androidndkgif

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             # Associated headers in the same location as their source
             # file are automatically included.
             #src/main/cpp/native-lib.cpp
             src/main/cpp/DataBlock.cpp
             src/main/cpp/BitWritingBlock.cpp
             src/main/cpp/GifDecoder.cpp
             src/main/cpp/GifEncoder.cpp
             src/main/cpp/GifFrame.cpp
             src/main/cpp/io_github_yylyingy_gifencodedecode_GifDecoder.cpp
             src/main/cpp/io_github_yylyingy_gifencodedecode_GifEncoder.cpp
             src/main/cpp/GCTGifEncoder.cpp
             src/main/cpp/LCTGifEncoder.cpp
             src/main/cpp/SimpleGCTEncoder.cpp
             src/main/cpp/BaseGifEncoder.cpp
             )

#include_directories(src/main/cpp/include)
#add_library( libjpeg SHARED IMPORTED )
#这句话是jpeg对应的so文件,so文件是放到ibs这个文件夹中(相对与cpp这个文件的位置)
#set_target_properties(libjpeg  PROPERTIES IMPORTED_LOCATION
#D:/Android/WorkSpaseForAS/TestLibjpeg/libjpeg/libs/${ANDROID_ABI}/libjpeg.so)

# Searches for a specified prebuilt library and stores the path as a
# variable. Because system libraries are included in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

find_library( # Sets the name of the path variable.
              log-lib
              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )


# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in the
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
                       androidndkgif

                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib}
                       #jnigraphics这个是android下面的bitmap.h对应的库
                       jnigraphics)

module library的build.gradle内容:

apply plugin: 'com.android.library'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"

    defaultConfig {
        minSdkVersion 14
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags ""//""-std=c++11"
            }
        }
        ndk{
            abiFilters 'x86','armeabi-v7a','armeabi'
        }
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    externalNativeBuild {
        cmake {
            path 'CMakeLists.txt'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.2.0'
    testCompile 'junit:junit:4.12'
}

做好了这些,便可以调用library里的java api实现gif解码了,
java 文件:
library

这里我封装成了SimpleGif库,可以像Glide那样一行代码即可
java代码调用范例:

SimpleGif.with(this).load(setupSampleFile()).into(imageView);

只需要一行代码,即可实现gif绘制到ImageView,api与Glide十分相似,并且解码使用了jni,效率应该大大提升效果图:
显示效果

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值