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

来源:互联网 发布:stayreal淘宝旗舰店 编辑:程序博客网 时间:2024/05/01 15:57

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,效率应该大大提升效果图:
显示效果

1 0
原创粉丝点击