下载地址:http://www.netsurf-browser.org/projects/libnsgif/
安卓Android项目地址:https://github.com/huzongyao/AndLibNsgif
这是netsurf浏览器的一个组件,可以单独使用,解析gif占用内存比较少,也比较简单。
windows下用opengl渲染,MinGW编译的,代码:
#include <stdio.h> #include <assert.h> #include <errno.h> #include <stdbool.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <sys/stat.h> #include <GL/freeglut.h> #include "nsgif/libnsgif.h" unsigned char *load_file(const char *path, size_t *data_size); void warning(const char *context, int code); void *bitmap_create(int width, int height); void bitmap_set_opaque(void *bitmap, bool opaque); bool bitmap_test_opaque(void *bitmap); unsigned char *bitmap_get_buffer(void *bitmap); void bitmap_destroy(void *bitmap); void bitmap_modified(void *bitmap); gif_animation gif; unsigned char *data; int index = 0; void close(){ /* clean up */ gif_finalise(&gif); free(data); } int decodeGif(const char* fname) { gif_bitmap_callback_vt bitmap_callbacks = { bitmap_create, bitmap_destroy, bitmap_get_buffer, bitmap_set_opaque, bitmap_test_opaque, bitmap_modified }; size_t size; gif_result code; /* create our gif animation */ gif_create(&gif, &bitmap_callbacks); /* load file into memory */ data = load_file(fname, &size); /* begin decoding */ do { code = gif_initialise(&gif, size, data); if (code != GIF_OK && code != GIF_WORKING) { warning("gif_initialise", code); return -1; } } while (code != GIF_OK); printf("# width %u \n", gif.width); printf("# height %u \n", gif.height); printf("# frame_count %u \n", gif.frame_count); printf("# frame_count_partial %u \n", gif.frame_count_partial); printf("# loop_count %u \n", gif.loop_count); printf("%u %u 256\n", gif.width, gif.height * gif.frame_count); return 0; } unsigned char* getFrame(int i){ unsigned char *image; gif_result code; code = gif_decode_frame(&gif, i); if (code != GIF_OK) warning("gif_decode_frame", code); image = (unsigned char *) gif.frame_image; return image; } unsigned char *load_file(const char *path, size_t *data_size) { FILE *fd; struct stat sb; unsigned char *buffer; size_t size; size_t n; fd = fopen(path, "rb"); if (!fd) { perror(path); exit(EXIT_FAILURE); } if (stat(path, &sb)) { perror(path); exit(EXIT_FAILURE); } size = sb.st_size; buffer = malloc(size); if (!buffer) { fprintf(stderr, "Unable to allocate %lld bytes\n", (long long) size); exit(EXIT_FAILURE); } n = fread(buffer, 1, size, fd); if (n != size) { perror(path); exit(EXIT_FAILURE); } fclose(fd); *data_size = size; return buffer; } void warning(const char *context, gif_result code) { fprintf(stderr, "%s failed: ", context); switch (code) { case GIF_INSUFFICIENT_FRAME_DATA: fprintf(stderr, "GIF_INSUFFICIENT_FRAME_DATA"); break; case GIF_FRAME_DATA_ERROR: fprintf(stderr, "GIF_FRAME_DATA_ERROR"); break; case GIF_INSUFFICIENT_DATA: fprintf(stderr, "GIF_INSUFFICIENT_DATA"); break; case GIF_DATA_ERROR: fprintf(stderr, "GIF_DATA_ERROR"); break; case GIF_INSUFFICIENT_MEMORY: fprintf(stderr, "GIF_INSUFFICIENT_MEMORY"); break; default: fprintf(stderr, "unknown code %i", code); break; } fprintf(stderr, "\n"); } void *bitmap_create(int width, int height) { return calloc(width * height, 4); } void bitmap_set_opaque(void *bitmap, bool opaque) { (void) opaque; /* unused */ assert(bitmap); } bool bitmap_test_opaque(void *bitmap) { assert(bitmap); return false; } unsigned char *bitmap_get_buffer(void *bitmap) { assert(bitmap); return bitmap; } void bitmap_destroy(void *bitmap) { assert(bitmap); free(bitmap); } void bitmap_modified(void *bitmap) { assert(bitmap); return; } void myDisplay(void) { // glClear(GL_COLOR_BUFFER_BIT); glDrawPixels(gif.width, gif.height, GL_RGBA, GL_UNSIGNED_BYTE, gif.frame_image); glutSwapBuffers(); } void myTimer(int i){ int delay; index++; if(index == gif.frame_count){ index = 0; } delay = gif.frames[index].frame_delay * 10; getFrame(index); glutPostRedisplay(); printf("Frame index[%d], delay[%d]\n", index, delay); glutTimerFunc(delay, myTimer, 1); } int main(int argc, char *argv[]) { decodeGif("test.gif"); glutInit(&argc, argv) ; glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); glutInitWindowPosition(300, 200); glutInitWindowSize(gif.width, gif.height); glutCreateWindow("Gif Show"); getFrame(index); glutTimerFunc(gif.frames[index].frame_delay * 10, &myTimer, 1); glRasterPos2f(-1, 1); //设置原点 glPixelZoom(1, -1); //y轴翻转 glutDisplayFunc(&myDisplay); glutMainLoop(); return 0; }
运行效果:
安卓平台通过jni调用:
安卓项目地址:https://github.com/huzongyao/AndLibNsgif
其他参考附件。
相关推荐
### 学习使用 Delphi for Android 调用 Java 类库 #### Delphi for Android 与 Java 类库的集成 Delphi for Android 是一个强大的跨平台开发工具,它允许开发者利用 Delphi 语言来构建高性能的原生 Android 应用...
【Android图表生成类库】 在Android开发中,有时我们需要展示数据,而图表是一种直观且有效的数据可视化方式。...通过查看和运行这些示例,开发者可以更深入地了解如何在Android应用中集成和使用图表生成类库。
1.实现android版本更新 2.对kotlin适配,调用更简单 3.自定义接口协议,可以不改变现有项目的协议就能使用 4.支持get,post请求 5.支持进度显示,对话框进度条,和通知栏进度条展示 6.支持后台下载 7.支持强制更新 8....
"Android 图表生成类库.zip"这个压缩包很可能包含了一些用于在Android平台上创建图表的开源库的源代码和相关文档。在这里,我们将详细探讨Android图表生成类库的相关知识点。 首先,Android图表生成类库可以帮助...
在Android应用开发中,数据可视化...以上知识点涵盖了Android图表生成类库的基础使用、高级特性、性能优化和用户体验等方面。在实际项目中,根据需求选择合适的库并充分利用其功能,可以极大地提升应用的数据展示效果。
- `1-120914120I50-L.jpg` 和 `1_120914120937_1.jpg`:可能是示例图表图片,帮助开发者理解类库的效果。 - `readme.md`:这是一个Markdown格式的文档,可能包含了类库的使用指南、示例代码、注意事项等内容,是...
Android-17类库,部分源码,帮助编程,导入即可使用。
### Android类库详解:构建移动应用的基石 在探索Android开发的世界时,深入理解其类库是必不可少的步骤。Android类库,作为Android框架的核心部分,提供了丰富的功能和API,帮助开发者构建高质量、高性能的移动...
在Android应用开发中,类库(Library)扮演着至关重要的角色,它们可以帮助开发者节省大量时间,提高代码质量,实现各种复杂功能。本篇文章将详细探讨Android开发中的常用类库及其重要性。 首先,我们来看看“dc....
"Android常用工具类库"是一个集合了多种实用功能的开源项目,包括图片缓存、下拉刷新、静默安装等功能。下面我们将详细探讨这些知识点。 1. 图片缓存: 在Android应用中,图片加载和显示是常见的需求,但不恰当的...
总之,这份"Android UI开发类库示例源码.zip"资源是学习和提升Android UI开发能力的宝贵资料,它覆盖了多种UI组件、布局和开源类库的使用,对于初学者和有经验的开发者来说,都是值得深入研究的对象。通过实际操作和...
"Android UI开发类库示例源码" 提供了一系列实用的资源和示例,帮助开发者在实际项目中提升效率,增强代码的可复用性和功能多样性。以下是对这些知识点的详细解释: 1. **Android UI组件**:Android提供了丰富的...
7. **示例应用**:可能有一个`app`模块,包含一个简单的Android应用,展示了类库的使用方法,便于开发者参考。 在Android图表生成类库中,常见的功能可能包括: - **多种图表类型**:如折线图、柱状图、饼图、散点...
本文将深入探讨“Android工具类库”的重要性、常见工具类及其使用场景,以及如何利用名为"AndroidUtilCode"的开源库来提升开发效率。 一、Android工具类库的重要性 1. 提高开发效率:工具类库集成了常见的功能模块...
Calligraphy 是一个用来简化 Android 应用使用自定义字体的类库, 该类库会自动查找应用中的 TextView 并设置其使用的字体。效果图:使用:添加依赖库(Download (.aar))dependencies { compile 'uk.co....