libexif库介绍

      libexif是一个用于解析、编辑和保存EXIF数据的库。它支持EXIF 2.1标准(以及2.2中的大多数)中描述的所有EXIF标签。它是用纯C语言编写的,不需要任何额外的库。源码地址:https://github.com/libexif/libexif ,最新发布版本为0.6.24,它的license为LGPL-2.1。

      EXIF全称为Exchangeable Image File format,可交换图像文件格式是专门为数码相机的照片设定的文件格式,可以记录数码照片的属性信息和拍摄数据EXIF可以附加于JPEG、TIFF、RIFF等文件之中,为其增加有关数码相机拍摄信息的内容和索引图或图像处理软件的版本信息。EXIF信息是可以被任意编辑的,因此只有参考的功能。
      EXIF信息以0xFFE1作为开头标记,后两个字节表示EXIF信息的长度。所以EXIF信息最大为64kB,而内部采用TIFF格式。

      libexif在Windows和Linux上编译过程:

      从https://github.com/libexif/libexif.git clone源码,然后切换到tag v0.6.24,执行:git checkout v0.6.24

      1.Linux上编译:

      (1).需要先安装依赖,执行如下命令:

sudo apt install autoconf autopoint libtool

      (2).编译源码,依次执行如下命令:

autoreconf -i
./configure --prefix=${PWD}/install --disable-docs
make
make install

      编译完成后在install目录下,会生成include、lib、share三个目录。

      2.Windows上编译:

      (1).新建libexif工程,参考Linux下生成的libexif.a中的文件,将相关文件添加到工程中;

      (2).将Linux下生成的config.h文件做调整并添加到libexif工程中,调整后的config.h内容如下:

/* config.h.  Generated from config.h.in by configure.  */
/* config.h.in.  Generated from configure.ac by autoheader.  */

/* Define to 1 if translation of program messages to the user's native
   language is requested. */
/* #undef ENABLE_NLS */

#define GETTEXT_PACKAGE "libexif-12"

#if defined(_MSC_VER)
	#  pragma warning(push)
	#  pragma warning(disable: 4127) // warning C4127: Conditional expression is constant
	#include <BaseTsd.h>
	typedef SSIZE_T ssize_t;
#endif

/* Define to 1 if you have the Mac OS X function CFLocaleCopyCurrent in the
   CoreFoundation framework. */
/* #undef HAVE_CFLOCALECOPYCURRENT */

/* Define to 1 if you have the Mac OS X function CFPreferencesCopyAppValue in
   the CoreFoundation framework. */
/* #undef HAVE_CFPREFERENCESCOPYAPPVALUE */

/* Define if the GNU dcgettext() function is already present or preinstalled.
   */
/* #undef HAVE_DCGETTEXT */

/* Define to 1 if you have the <dlfcn.h> header file. */
/* #undef HAVE_DLFCN_H */

/* Define if the GNU gettext() function is already present or preinstalled. */
/* #undef HAVE_GETTEXT */

/* Define if you have the iconv() function and it works. */
/* #undef HAVE_ICONV */

/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1

/* Define to 1 if you have the `localtime_r' function. */
/* #undef HAVE_LOCALTIME_R */

/* Define to 1 if you have localtime_s() */
#define HAVE_LOCALTIME_S 1

/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1

/* Define to 1 if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1

/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1

/* Define to 1 if you have the <strings.h> header file. */
/* #undef HAVE_STRINGS_H */

/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1

/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1

/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1

/* Define to 1 if you have the <unistd.h> header file. */
/* #undef HAVE_UNISTD_H */

/* Define as const if the declaration of iconv() needs const. */
/* #undef ICONV_CONST */

/* Define to the sub-directory where libtool stores uninstalled libraries. */
//#define LT_OBJDIR ".libs/"

/* Name of package */
#define PACKAGE "libexif"

/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "libexif-devel@lists.sourceforge.net"

/* Define to the full name of this package. */
#define PACKAGE_NAME "EXIF library"

/* Define to the full name and version of this package. */
#define PACKAGE_STRING "EXIF library 0.6.24"

/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libexif"

/* Define to the home page for this package. */
#define PACKAGE_URL "https://libexif.github.io/"

/* Define to the version of this package. */
#define PACKAGE_VERSION "0.6.24"

/* Define to 1 if all of the C90 standard headers exist (not just the ones
   required in a freestanding environment). This macro is provided for
   backward compatibility; new code need not use it. */
#define STDC_HEADERS 1

/* Version number of package */
#define VERSION "0.6.24"

/* Number of bits in a file offset, on hosts where this is settable. */
/* #undef _FILE_OFFSET_BITS */

/* Define for large files, on AIX-style hosts. */
/* #undef _LARGE_FILES */

/* Define to `__inline__' or `__inline' if that's what the C compiler
   calls it, or to nothing if 'inline' is not supported under any name.  */
#ifndef __cplusplus
/* #undef inline */
#endif

      (3).将Linux上生成的_stdint.h文件也添加到此工程中;

      (4).编译工程生成libexif.lib静态库。

      对带有exif信息的jpg图像生成缩略图的测试代码如下:

int test_libexif_thumbnail()
{
	// reference: https://github.com/libexif/libexif/blob/master/contrib/examples/thumbnail.c
	// Create an ExifLoader object to manage the EXIF loading process
	ExifLoader* l = exif_loader_new();
	if (!l) {
		std::cerr << "Error: fail to exif_loader_new\n";
		return -1;
	}

#ifdef _MSC_VER
	constexpr char* jpg_name{ "../../../test_images/exif.jpg" };
#else
	constexpr char* jpg_name{ "test_images/exif.jpg" };
#endif

	// Load the EXIF data from the image file
	exif_loader_write_file(l, jpg_name);

	// Get a pointer to the EXIF data
	ExifData* ed = exif_loader_get_data(l);
	if (!ed) {
		std::cerr << "Error: fail to exif_loader_get_data\n";
		return -1;
	}

	// The loader is no longer needed--free it
	exif_loader_unref(l);
	
	// Make sure the image had a thumbnail before trying to write it
	if (ed->data && ed->size) {
		std::cout << "exif data size: " << ed->size << "\n";

		char thumb_name[1024];
		snprintf(thumb_name, sizeof(thumb_name), "%s_thumb.jpg", jpg_name);

		FILE* thumb = fopen(thumb_name, "wb");
		if (!thumb) {
			std::cerr << "Error: fail to fopen: " << thumb_name << "\n";
			return -1;
		}

		// Write the thumbnail image to the file
		fwrite(ed->data, 1, ed->size, thumb);
		fclose(thumb);
	}

	exif_data_unref(ed);

	return 0;
}

      Windows上和Linux上的执行结果如下图所示:

      GitHub:https://github.com/fengbingchun/OpenCV_Test

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/300315.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何保障开放网络边界安全?

针对开放式网络&#xff08;办事大厅、视频网络等&#xff09;&#xff0c;如何在内部网络构建起一道安全屏障&#xff0c;有效解决广大用户普遍存在的无法保证网络边界完整、边界安全、公共场所终端摄像头管理、办事大厅智能设备&#xff08;一体机等&#xff09;管理、开放场…

【AI视野·今日CV 计算机视觉论文速览 第283期】Thu, 4 Jan 2024

AI视野今日CS.CV 计算机视觉论文速览 Thu, 4 Jan 2024 Totally 85 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computer Vision Papers LEAP-VO: Long-term Effective Any Point Tracking for Visual Odometry Authors Weirong Chen, Le Chen, Rui Wang, Marc P…

信源编码与信道转移矩阵

目录 一. 信息论模型 二. 点对点通信模型 三. 信源编码 四. 信道转移矩阵 4.1 二进制对称信道 4.2 二进制擦除信道 五. 小结 &#xff08;1&#xff09;信道直射与反射 &#xff08;2&#xff09;信道散射 &#xff08;3&#xff09; 信道时变性 一. 信息论模型 194…

Python 面向对象之反射

Python 面向对象之反射 【一】概念 反射是指通过对象的属性名或者方法名来获取对象的属性或调用方法的能力反射还指的是在程序额运行过程中可以动态获取对象的信息(属性和方法) 【二】四个内置函数 又叫做反射函数 万物皆对象&#xff08;整数、字符串、函数、模块、类等等…

thinkphp6入门(15)-- 模型动态构建查询条件

背景 我使用thinkphp6的模型写数据库查询&#xff0c;有多个where条件&#xff0c;但是不确定是否需要添加某个where条件&#xff0c;怎么才能动态得生成查询 链式查询 在ThinkPHP 6中&#xff0c;可以使用链式查询方法来动态地构建查询条件。可以根据参数的值来决定是否添加…

【Docker基础一】Docker安装Elasticsearch,Kibana,IK分词器

安装elasticsearch 下载镜像 查看版本&#xff1a;Elasticsearch Guide [8.11] | Elastic # 下载镜像 docker pull elasticsearch:7.17.16 # 查看镜像是否下载成功 docker images创建网络 因为需要部署kibana容器&#xff0c;要让es和kibana容器互联 # 创建一个网络&…

2024阿里云优惠_阿里云活动中心

2024年阿里云优惠活动大全&#xff0c;包括阿里云服务器优惠活动清单、配置价格表、域名优惠活动、阿里云建站活动、阿里云优惠代金券免费领取、对象存储OSS活动、企业邮箱优惠、无影云电脑优惠、CDN特惠等等&#xff0c;阿里云百科aliyunbaike.com分享2024阿里云优惠活动大全_…

【JAVA】Iterator 和 ListIterator 有什么区别?

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a; JAVA ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 在Java中&#xff0c;遍历集合是日常编程中常见的任务&#xff0c;而Iterator和ListIterator作为遍历集合的两个主要接口&#xff0…

MacOS M1/M2 Go Debug 配置

前言 换电脑&#xff0c;Go 环境带来一些麻烦&#xff0c;耽误很多时间&#xff0c;稍作记录。 原始电脑是 Mac 旧款&#xff0c;CPU x86 构型&#xff0c;新电脑 M2&#xff0c;因为旧电脑里本地文件很多&#xff0c;为了简化搬迁&#xff0c;还是用了 Mac 自带的迁移&#x…

[论文阅读] Revisiting Feature Propagation and Aggregation in Polyp Segmentation

[论文地址] [代码] [MICCAI 23] Abstract 息肉的准确分割是筛查过程中有效诊断结直肠癌的关键步骤。 由于能够有效捕获多尺度上下文信息&#xff0c;普遍采用类似UNet 的编码器-解码器框架。 然而&#xff0c;两个主要限制阻碍了网络实现有效的特征传播和聚合。 首先&#xff…

AI教我学编程之C#关键字

AI教我学编程系列学习第三课 — C#关键字 前言重点先知关键字分类保留字上下文关键字 对话AI首遇波澜调整指令第一次第二次第三次直到我提出如下指令 人工智能&#xff1f;阶段总结 知识拓展1、Ecma和ISO是什么&#xff1f;2、System&#xff0c;dllhost.exe&#xff0c;taskmg…

力扣:438. 找到字符串中所有字母异位词 题解

Problem: 438. 找到字符串中所有字母异位词 438. 找到字符串中所有字母异位词 预备知识解题思路复杂度Code其它细节推荐博客或题目博客题目滑动窗口哈希表 预备知识 此题用到了双指针算法中的滑动窗口思想&#xff0c;以及哈希表的运用。c中是unordered_map。如果对此不了解的u…

江科大STM32

目录 STM32简介 STM32简介 我们主要学习的就是STM32的外设。 NVIC&#xff1a;内核里面用于管理中断的设备&#xff0c;比如配置中断优先级这些东西SysTick&#xff1a;内核里面的定时器&#xff0c;主要用来给操作系统提供定时服务的&#xff0c;STM32是可以加入操作系统的&am…

FlinkSQL中【FULL OUTER JOIN】使用实例分析(坑)

Flink版本&#xff1a;flink1.14 最近有【FULL OUTER JOIN】场景的实时数据开发需求&#xff0c;想要的结果是&#xff0c;左右表来了数据都下发数据&#xff1b;左表存在的数据&#xff0c;右表进来可以关联下发&#xff08;同样&#xff0c;右表存在的数据&#xff0c;左表进…

计算机毕业设计------SSM二手交易网站

项目介绍 该项目分为前后台&#xff0c;前台普通用户角色&#xff0c;后台管理员角色。 管理员主要功能如下&#xff1a; 登陆,商品分类管理,商品管理,商品订单管理,用户管理等功能。 用户角色主要功能如下&#xff1a; 包含以下功能&#xff1a;查看所有商品,用户登陆注册…

2023.12.30周报

目录 摘要 ABSTRACT 一、文献阅读 1、题目 2、摘要 3、创新点 4、文章解读 1、Introduction 2、时间序列的季节趋势表征 3、 季节趋势对比学习框架 4、实验 5、结论 二、ARIMA 一、ARIMA模型的基本思想 二、ARIMA模型的数学表达式 三、差分过程 1、什么是差分…

循环队列的队空队满情况

有题目&#xff1a; 循环队列放在一维数组A[0....M-1]中&#xff0c;end1指向队头元素&#xff0c;end2指向队尾元素的后一个位置。假设队列两端均可进行入队和出队操作&#xff0c;队列中最多能容纳M-1个元素。初始时为空。下列判断队空和队满的条件中&#xff0c;正确的是 …

计算机毕业设计 基于Javaweb的城乡居民基本医疗信息管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

逆置算法和数组循环移动算法

元素逆置 概述&#xff1a;其实就是将 第一个元素和最后一个元素交换&#xff0c;第二个元素和倒数第二个元素交换&#xff0c;依次到中间位置。用途&#xff1a;可用于数组的移动&#xff0c;字符串反转&#xff0c;链表反转操作&#xff0c;栈和队列反转等操作。 逆置图解 …

Cadence Editor 关于画PCB相关内容

目录 一 新建PCB文件 二 指定封装库 三 导入网表 四 放置器件 五 绘制板框 六 精准定位 七 原理图与PCB的交互 八 飞线设置 九 层管理 布局布线阶段需要显示的层 十 器件位置相关 1 器件选取的基准点 2 旋转 3 对齐 4 把器件移动到底层或顶层 5 锁定与解锁 6…