`
hzy3774
  • 浏览: 993144 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
社区版块
存档分类
最新评论

Android使用libnsgif类库解gif图片

阅读更多

下载地址: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
 其他参考附件。

 

  • 大小: 473.7 KB
  • 大小: 74.2 KB
  • 大小: 394.4 KB
分享到:
评论

相关推荐

    学习使用Delphi for android 调用Java类库

    ### 学习使用 Delphi for Android 调用 Java 类库 #### Delphi for Android 与 Java 类库的集成 Delphi for Android 是一个强大的跨平台开发工具,它允许开发者利用 Delphi 语言来构建高性能的原生 Android 应用...

    Android图表生成类库Demo

    【Android图表生成类库】 在Android开发中,有时我们需要展示数据,而图表是一种直观且有效的数据可视化方式。...通过查看和运行这些示例,开发者可以更深入地了解如何在Android应用中集成和使用图表生成类库。

    Android 更新版本类库

    1.实现android版本更新 2.对kotlin适配,调用更简单 3.自定义接口协议,可以不改变现有项目的协议就能使用 4.支持get,post请求 5.支持进度显示,对话框进度条,和通知栏进度条展示 6.支持后台下载 7.支持强制更新 8....

    Android 图表生成类库.zip

    "Android 图表生成类库.zip"这个压缩包很可能包含了一些用于在Android平台上创建图表的开源库的源代码和相关文档。在这里,我们将详细探讨Android图表生成类库的相关知识点。 首先,Android图表生成类库可以帮助...

    Android 图表生成类库

    在Android应用开发中,数据可视化...以上知识点涵盖了Android图表生成类库的基础使用、高级特性、性能优化和用户体验等方面。在实际项目中,根据需求选择合适的库并充分利用其功能,可以极大地提升应用的数据展示效果。

    Android 图表生成类库.rar

    - `1-120914120I50-L.jpg` 和 `1_120914120937_1.jpg`:可能是示例图表图片,帮助开发者理解类库的效果。 - `readme.md`:这是一个Markdown格式的文档,可能包含了类库的使用指南、示例代码、注意事项等内容,是...

    Android-17类库

    Android-17类库,部分源码,帮助编程,导入即可使用。

    android类库的详细介绍

    ### Android类库详解:构建移动应用的基石 在探索Android开发的世界时,深入理解其类库是必不可少的步骤。Android类库,作为Android框架的核心部分,提供了丰富的功能和API,帮助开发者构建高质量、高性能的移动...

    Android开发常用类库

    在Android应用开发中,类库(Library)扮演着至关重要的角色,它们可以帮助开发者节省大量时间,提高代码质量,实现各种复杂功能。本篇文章将详细探讨Android开发中的常用类库及其重要性。 首先,我们来看看“dc....

    Android常用工具类库

    "Android常用工具类库"是一个集合了多种实用功能的开源项目,包括图片缓存、下拉刷新、静默安装等功能。下面我们将详细探讨这些知识点。 1. 图片缓存: 在Android应用中,图片加载和显示是常见的需求,但不恰当的...

    Android ui开发类库示例源码.zip源码资源下载

    总之,这份"Android UI开发类库示例源码.zip"资源是学习和提升Android UI开发能力的宝贵资料,它覆盖了多种UI组件、布局和开源类库的使用,对于初学者和有经验的开发者来说,都是值得深入研究的对象。通过实际操作和...

    Android ui开发类库示例源码.rar

    "Android UI开发类库示例源码" 提供了一系列实用的资源和示例,帮助开发者在实际项目中提升效率,增强代码的可复用性和功能多样性。以下是对这些知识点的详细解释: 1. **Android UI组件**:Android提供了丰富的...

    Android 图表生成类库.zip源码资源下载

    7. **示例应用**:可能有一个`app`模块,包含一个简单的Android应用,展示了类库的使用方法,便于开发者参考。 在Android图表生成类库中,常见的功能可能包括: - **多种图表类型**:如折线图、柱状图、饼图、散点...

    android工具类库

    本文将深入探讨“Android工具类库”的重要性、常见工具类及其使用场景,以及如何利用名为"AndroidUtilCode"的开源库来提升开发效率。 一、Android工具类库的重要性 1. 提高开发效率:工具类库集成了常见的功能模块...

    Android字体类库Calligraphy.zip

    Calligraphy 是一个用来简化 Android 应用使用自定义字体的类库, 该类库会自动查找应用中的 TextView 并设置其使用的字体。效果图:使用:添加依赖库(Download (.aar))dependencies {  compile 'uk.co....

Global site tag (gtag.js) - Google Analytics