当前位置: 首页 > 工具软件 > libexif > 使用案例 >

libexif的使用

鲁波光
2023-12-01

wiki上有EXIF的介绍,不抄了 http://zh.wikipedia.org/wiki/EXIF

分析exif数据的c库有libexif, c++库有exiv2。exiv2比libexif支持更多格式,最近更新也比较活跃。这里简单介绍下如何使用libexif

libexif主要的数据结构有ExifData, ExifContent, ExifEntry

ExifData

包含了所有的exif数据,可以简单地用exif_data_new_from_file(const char* path)来创建,其内部使用ExifLoader. 也可以new一个loader手动载入然后取出ExifData.

ExifContent

包含了单个IFD的所有tag,可以用 exif_data_foreach_contetn()来遍历操作ExifData中的ExifContent,用exif_content_get_ifd来读取一个content所属的ifd

ifd有如下值

EXIF_IFD_0 	
EXIF_IFD_1 	
EXIF_IFD_EXIF 	
EXIF_IFD_GPS 	
EXIF_IFD_INTEROPERABILITY 	
EXIF_IFD_COUNT 

其中 EXIF_IFD_COUNT表示无效的ifd,说明取ifd出错了

ifd可以用exif_ifd_get_name(ExifIfd ifd)来把枚举转换成相应的名字

ExifEntry

保存了一个tag的信息,ExifContent提供了一个函数来提取ExifEntry

exif_content_get_entry(ExifContent*, ExifTag)

同时,ExifData提供了一个宏来提取ExifEntry,其实就是对每个ifd逐个调用exif_content_get_entry

#define exif_data_get_entry(d,t) 	\
(exif_content_get_entry(d->ifd[EXIF_IFD_0],t) ?                 \
         exif_content_get_entry(d->ifd[EXIF_IFD_0],t) :                 \
         exif_content_get_entry(d->ifd[EXIF_IFD_1],t) ?                 \
         exif_content_get_entry(d->ifd[EXIF_IFD_1],t) :                 \
         exif_content_get_entry(d->ifd[EXIF_IFD_EXIF],t) ?              \
         exif_content_get_entry(d->ifd[EXIF_IFD_EXIF],t) :              \
         exif_content_get_entry(d->ifd[EXIF_IFD_GPS],t) ?               \
         exif_content_get_entry(d->ifd[EXIF_IFD_GPS],t) :               \
         exif_content_get_entry(d->ifd[EXIF_IFD_INTEROPERABILITY],t) ?  \
         exif_content_get_entry(d->ifd[EXIF_IFD_INTEROPERABILITY],t) : NULL)


有了ExifEntry,我们就可以读取tag的信息了。ExifEntry有个ExifTag的数据成员tag,获取tag信息主要的几个函数有

const char* exif_tag_get_title_in_ifd(ExifTag, ExifIfd)

const char* exif_entry_get_value(ExifEntry* entry, char* val, unsigned int maxlen)



有了这些就可以写个小程序来读取照片的exif信息了

#include <cstdio>
#include <cstring>
#include <libexif/exif-data.h>

void read_exif_entry(ExifEntry *ee, void* ifd)
{
	char v[1024];
//	strncpy(t, exif_tag_get_title_in_ifd(ee->tag, exif_entry_get_ifd(ee)), sizeof(t));
//	strncpy(t, exif_tag_get_title_in_ifd(ee->tag, *((ExifIfd*)ifd)), sizeof(t));
	//trim t
	printf("%s: %s\n"
//			, exif_tag_get_name_in_ifd(ee->tag, *((ExifIfd*)ifd))
			, exif_tag_get_title_in_ifd(ee->tag, *((ExifIfd*)ifd))
//			, exif_tag_get_description_in_ifd(ee->tag, *((ExifIfd*)ifd))
			, exif_entry_get_value(ee, v, sizeof(v)));
}

void read_exif_content(ExifContent *ec, void *user_data)
{
	ExifIfd ifd = exif_content_get_ifd(ec);
	if (ifd == EXIF_IFD_COUNT)
		fprintf(stderr, "exif_content_get_ifd error");
	printf("======IFD: %d %s======\n", ifd, exif_ifd_get_name(ifd));
	exif_content_foreach_entry(ec, read_exif_entry, &ifd);
}

int main(int argc, char** argv)
{
	ExifData* ed = exif_data_new_from_file(argv[1]);
	if (!ed) {
		fprintf(stderr, "An error occur");
		return 1;
	}

	//exif_data_set_option(ed, 
	exif_data_foreach_content(ed, read_exif_content, NULL);

	exif_data_unref(ed);

	return 0;
}



 类似资料: