下载地址: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类库
Android 图表生成类库,方便生成各式各样的图表等信息,非常适合项目直接使用
Android开发常用类库
1.实现android版本更新 2.对kotlin适配,调用更简单 3.自定义接口协议,可以不改变现有项目的协议就能使用 4.支持get,post请求 5.支持进度显示,对话框进度条,和通知栏进度条展示 6.支持后台下载 7.支持强制更新 8....
Android图表生成类库Demo
Android 图表生成类库
Android SDK类库简介 Android SDK类库简介 Android SDK类库简介 Android SDK类库简介
Android-17类库,部分源码,帮助编程,导入即可使用。
Android 图表生成类库.zip源码资源下载Android 图表生成类库.zip源码资源下载
Android 图表生成类库.rar
Android程序研发源码Android 图表生成类库.zip
AS3中gif类库,ActionScript,gif类库,AS3打印gif AS3中gif类库,ActionScript,gif类库,AS3打印gif
Android图表生成类库.zip
Android程序研发源码Android ui开发类库示例源码.zip
Android ui开发类库示例源码.zip源码资源下载Android ui开发类库示例源码.zip源码资源下载