exif格式及解析库easyexif使用介绍

news2024/9/20 15:02:53

1.  JPEG文件结构和EXIF数据的信息

            JPEG文件以字符串"0xFFD8"开头表示图像信息开始,以字符串"0xFFD9"结尾表示图像信息结束。

            在JPEG文件头中有一系列"0xFF??"格式的数据段,称为"标识",用来标记JPEG文件的信息段。

        0xFFE0-0xFFEF之间的标识符称为"应用标记",没有被常规JPEG文件利用。EXIF就是利用这些信息段记录拍摄信息,如快门速度、光圈值等,甚至包括全球定位信息。

        EXIF定义的数据结构(APP1)采用"Intel"的小端字节顺序方案,且包含JPEG格式的缩略图。

        EXIF数据以ASCII字符"Exif"和2个字节的0x00开始,后面就是EXIF的数据,使用TIFF格式来存储数据。

总的来说,JPEG文件头中有一些预定义的标识符,其中应用标记0xFFE0-0xFFEF没有被常规JPEG文件使用。EXIF正是利用这些应用标记来存储拍摄信息等数据,采用TIFF格式组织数据。应用软件可以读取这些EXIF数据并解析出相关信息

        EXIF 是数码相机拍摄照片时记录在照片文件中的元数据标准。它包含了照片的拍摄时间、相机型号、光圈、快门速度、ISO 感光度、白平衡等各种拍摄参数信息。这些信息对于后期处理和管理数码照片非常有用。

        EXIF 数据通常以二进制形式嵌入在照片文件的头部或尾部,常见的文件格式包括 JPEG、TIFF 和 RAW 格式。不同的相机品牌和型号可能会记录不同种类的EXIF 信息。

       以 JPEG 文件为例,EXIF 数据通常位于 JPEG 文件头的 APP1 块中。用户可以使用各种软件查看和编辑 EXIF 数据,如 Windows 系统自带的图片浏览器、Adobe Lightroom、Photoshop 等。

        EXIF 数据为照片管理和后期处理提供了丰富的元数据信息。摄影爱好者可以利用 EXIF 数据分类、排序、搜索照片,并根据拍摄参数优化后期编辑。总的来说, EXIF 格式为数码摄影带来了很大的便利。

2. EXIF 数据通常包含以下几类信息:

       2.1 基本信息:

                拍摄时间和日期

                相机型号、制造商

                镜头焦距

                曝光时间

                光圈值

                ISO 感光度

                白平衡设置

                闪光灯状态

2.2 位置信息:

        GPS 坐标

        拍摄位置

        拍摄方向

2.3 图像处理信息:

        色彩空间

        图像尺寸和分辨率

        图像方向(横/竖拍)

        数字变焦倍数

2.4 版权信息:

        摄影师姓名

        版权所有者

        版权声明

EXIF 数据可以通过各种软件查看和编辑。常见的操作包括:

        查看照片的拍摄参数和位置信息

        根据 EXIF 数据对照片进行分类和管理

        修改 EXIF 数据,如添加拍摄地点、修改日期时间等

        将 EXIF 数据嵌入到新拍摄的照片中

        总的来说,EXIF 格式为数码摄影带来了许多便利,为摄影爱好者提供了丰富的元数据信息。掌握 EXIF 数据的使用技巧,可以大大提高照片管理和后期编辑的效率。

3. 可以使用‘MagicEXIF 元数据编辑器‘’软件进行查看jpeg文件信息

4. easyexif库介绍

        通过easyExif库快速方便的读取exif信息。下载地址为:https://github.com/mayanklahiri/easyexif

easyexif C++ 版本的主要特点如下:

        轻量级和跨平台

                仅依赖标准 C++ 库,没有其他外部依赖

                可以在 Windows、macOS 和 Linux 等主流操作系统上使用

        简单易用的 API

                提供了 EXIFInfo 类来表示 EXIF 数据

                通过简单的成员函数获取各种 EXIF 信息

        支持多种文件格式

                支持 JPEG、TIFF 和 DNG 等常见图像文件格式

         灵活的 EXIF 数据读写

                可以从文件或二进制数据中读取 EXIF 信息

                支持修改 EXIF 数据并写回文件

示例demo:

#include <stdio.h>
#include "exif.h"

int main(int argc, char *argv[]) {
  if (argc < 2) {
    printf("Usage: demo <JPEG file>\n");
    return -1;
  }

  // Read the JPEG file into a buffer
  FILE *fp = fopen(argv[1], "rb");
  if (!fp) {
    printf("Can't open file.\n");
    return -1;
  }
  fseek(fp, 0, SEEK_END);
  unsigned long fsize = ftell(fp); //获取文件长度
  rewind(fp);                     //将文件内部的位置指针重新指向一个流的开头
  unsigned char *buf = new unsigned char[fsize];
  if (fread(buf, 1, fsize, fp) != fsize) {
    printf("Can't read file.\n");
    delete[] buf;
    return -2;
  }
  fclose(fp);

  // Parse EXIF
  easyexif::EXIFInfo result;
  int code = result.parseFrom(buf, fsize); //使用easyexif库解析exif信息
  delete[] buf;
  if (code) {
    printf("Error parsing EXIF: code %d\n", code);
    return -3;
  }

  // Dump EXIF information
  printf("Camera make          : %s\n", result.Make.c_str());
  printf("Camera model         : %s\n", result.Model.c_str());
  printf("Software             : %s\n", result.Software.c_str());
  printf("Bits per sample      : %d\n", result.BitsPerSample);
  printf("Image width          : %d\n", result.ImageWidth);
  printf("Image height         : %d\n", result.ImageHeight);
  printf("Image description    : %s\n", result.ImageDescription.c_str());
  printf("Image orientation    : %d\n", result.Orientation);
  printf("Image copyright      : %s\n", result.Copyright.c_str());
  printf("Image date/time      : %s\n", result.DateTime.c_str());
  printf("Original date/time   : %s\n", result.DateTimeOriginal.c_str());
  printf("Digitize date/time   : %s\n", result.DateTimeDigitized.c_str());
  printf("Subsecond time       : %s\n", result.SubSecTimeOriginal.c_str());
  printf("Exposure time        : 1/%d s\n",
         (unsigned)(1.0 / result.ExposureTime));
  printf("F-stop               : f/%.1f\n", result.FNumber);
  printf("Exposure program     : %d\n", result.ExposureProgram);
  printf("ISO speed            : %d\n", result.ISOSpeedRatings);
  printf("Subject distance     : %f m\n", result.SubjectDistance);
  printf("Exposure bias        : %f EV\n", result.ExposureBiasValue);
  printf("Flash used?          : %d\n", result.Flash);
  printf("Flash returned light : %d\n", result.FlashReturnedLight);
  printf("Flash mode           : %d\n", result.FlashMode);
  printf("Metering mode        : %d\n", result.MeteringMode);
  printf("Lens focal length    : %f mm\n", result.FocalLength);
  printf("35mm focal length    : %u mm\n", result.FocalLengthIn35mm);
  printf("GPS Latitude         : %f deg (%f deg, %f min, %f sec %c)\n",
         result.GeoLocation.Latitude, result.GeoLocation.LatComponents.degrees,
         result.GeoLocation.LatComponents.minutes,
         result.GeoLocation.LatComponents.seconds,
         result.GeoLocation.LatComponents.direction);
  printf("GPS Longitude        : %f deg (%f deg, %f min, %f sec %c)\n",
         result.GeoLocation.Longitude, result.GeoLocation.LonComponents.degrees,
         result.GeoLocation.LonComponents.minutes,
         result.GeoLocation.LonComponents.seconds,
         result.GeoLocation.LonComponents.direction);
  printf("GPS Altitude         : %f m\n", result.GeoLocation.Altitude);
  printf("GPS Precision (DOP)  : %f\n", result.GeoLocation.DOP);
  printf("Lens min focal length: %f mm\n", result.LensInfo.FocalLengthMin);
  printf("Lens max focal length: %f mm\n", result.LensInfo.FocalLengthMax);
  printf("Lens f-stop min      : f/%.1f\n", result.LensInfo.FStopMin);
  printf("Lens f-stop max      : f/%.1f\n", result.LensInfo.FStopMax);
  printf("Lens make            : %s\n", result.LensInfo.Make.c_str());
  printf("Lens model           : %s\n", result.LensInfo.Model.c_str());
  printf("Focal plane XRes     : %f\n", result.LensInfo.FocalPlaneXResolution);
  printf("Focal plane YRes     : %f\n", result.LensInfo.FocalPlaneYResolution);

  return 0;
}

 运行结果如下:

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SQL 获取employees中的first_name

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 描述 现有employee…

在 PostgreSQL 里如何处理数据的存储优化和数据库备份的时间窗口冲突?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01;&#x1f4da;领书&#xff1a;PostgreSQL 入门到精通.pdf 文章目录 在 PostgreSQL 中处理数据存储优化和数据库备份时间窗口冲突 在 PostgreSQL 中处理数据存储优化和数据…

智能测评养号系统:解决效率与成本难题,让测评效率翻倍

各位跨境电商从业者好,我是陈哥。今天我想和大家分享一下关于测评养号系统的一些见解和经验。 近期,不少做测评工作室的朋友向我咨询,希望能找到一种新型的测评养号系统,以解决当前面临的诸多问题,如成本高昂、效率低下、账号纯净度不够、操作不便捷等。 众所周知,测评养号系统…

某客户管理系统Oracle RAC节点异常重启问题详细分析记录

一、故障概述 某日10:58分左右客户管理系统数据库节点1所有实例异常重启&#xff0c;重启后业务恢复正常。经过分析发现&#xff0c;此次实例异常重启的是数据库节点1。 二、故障原因分析 1、数据库日志分析 从节点1的数据库日志来看&#xff0c;10:58:49的时候数据库进程开始…

Qt实现IP地址输入框-自定义控件

在 许多应用程序中&#xff0c;我们经常需要使用IP地址。为了方便用户输入和处理&#xff0c;一个好的解决方案是使用自定义控件。本示例代码使用Qt编写一个名为“IPAddress”的自定义控件来实现IP地址的输入功能。通过使用此控件&#xff0c;用户可以方便地输入和处理IP地址。…

【源码交付】一站式自助数据分析解决方案(JVS-BI):系统架构蓝图

1.引言 JVS-BI是一体化、自助式的数据分析平台&#xff0c;它采用的高度集成化的思路&#xff0c;针对企业级用户&#xff0c;提供集中仓库便捷分析的企业级数据开发套件&#xff0c;解决企业各种需要数据分析的场景&#xff0c;多种数据库、多种业务系统、跨库关联、离线数据…

新版网页无插件H.265播放器EasyPlayer.js如何测试demo视频?

H5无插件流媒体播放器EasyPlayer属于一款高效、精炼、稳定且免费的流媒体播放器&#xff0c;可支持多种流媒体协议播放&#xff0c;支持H.264与H.265编码格式&#xff0c;性能稳定、播放流畅&#xff1b;支持WebSocket-FLV、HTTP-FLV&#xff0c;HLS&#xff08;m3u8&#xff0…

【病毒分析】Babyk加密器分析-NAS篇

1.前情提要 继上篇分析了关于Babyk加密器在Windows环境的行为特征&#xff0c;本篇是针对NAS系统的相关分析。 2.总体行为 3.密钥下发&#xff08;Builder.exe) 这里可以通过VS生成了Builder.exe来实现对其Builder过程进行分析&#xff0c;可以看到主要是对这部分文件的处理…

Excel 学习手册 - 精进版(包括各类复杂函数及其嵌套使用)

作为程序员从未想过要去精进一下 Excel 办公软件的使用方法&#xff0c;以前用到某功能都是直接百度&#xff0c;最近这两天跟着哔哩哔哩上的戴戴戴师兄把 Excel 由里到外学了一遍&#xff0c;收获良多。程序员要想掌握这些内容可以说是手拿把掐&#xff0c;对后续 Excel 的运用…

Elastic 线下 Meetup 将于 2024 年 7 月 27 号在深圳举办

2024 Elastic Meetup 深圳站活动&#xff0c;由 Elastic、腾讯、新智锦绣联合举办&#xff0c;现诚邀广大技术爱好者及开发者参加。 时间地点 2024年 7 月 27 日 13:30-18:00 活动地点 中国深圳 南山区海天二路 33 号腾讯滨海大厦 北塔 3 楼多功能厅 ​ 活动流程 14:00-15…

如何轻松统管虚拟化和容器环境?一文了解 SmartX 虚拟化容器融合基础设施

随着越来越多的企业完成应用容器化改造&#xff0c;应用负载的运行环境也变得越来越复杂——近 60% 的企业正在或计划同时采用虚拟化环境和容器环境运行应用系统*&#xff0c;以满足不同业务在性能和敏捷性等方面的不同需求。不过&#xff0c;虚拟化和容器平台通常由不同的厂商…

基于单片机STC89C52和GSM实现的远程拨号开锁设计(含文档、源码与proteus仿真,以及系统详细介绍)

本篇文章论述的是基于单片机STC89C52和GSM实现的远程拨号开锁设计的详情介绍&#xff0c;如果对您有帮助的话&#xff0c;还请关注一下哦&#xff0c;如果有资源方面的需要可以联系我。 目录 摘要 仿真图 单片机系统流程图 实物图 代码 系统论文 资源下载 摘要 本文介…

汇编教程1

本教程主要教大家如何使用vscode插件编写汇编语言&#xff0c;这样更方便&#xff0c;不用在32位虚拟机中编写汇编语言&#xff0c;后续的汇编实验代码都是使用vscode编写&#xff0c;话不多说&#xff0c;开始教学 安装vscode 如果已经安装过vscode&#xff0c;可以跳过这一…

Spring事务原理、Spring事务传播机制

Spring的EnableTransactionManagement 和Transactional原理 Configuration EnableTransactionManagement public class AppConfig { // 配置类内容 } Service public class MyService { Transactional public void processPayment(Payment payment) { // 这里是业…

聚焦 Navicat 17 新特性 | 数据字典提升数据结构清晰度

随着 Navicat 17 的发布&#xff0c;在业界引起了广泛的共鸣与热议。我们曾深入剖析其众多革新特性&#xff0c;包括模型设计创新与优化、高效的查询与配置、用户界面交互体验再升级&#xff0c;以及它如何原生适配国产 Linux ARM 平台和麒麟操作系统等&#xff0c;这些新特性实…

Maven学习——Maven的下载、安装与配置(详细攻略!)

目录 前言 1.下载与安装 2.配置Maven的环境变量 3.配置Maven的本地仓库 4. 配置Maven的镜像远程仓库 前言 我在之前写了一篇博客&#xff0c;是介绍Maven的基本概念和下载安装&#xff0c;但是由于篇幅过长&#xff0c;Maven的下载与安装写的并不详细&#x1f436;&#x…

redis删除策略和淘汰策略

1、redis的删除策略 Redis 是一种内存级数据库&#xff0c;数据都存在内存中&#xff0c;但是针对于已经过期的数据&#xff0c;reids 不 会立刻删除只是会存储在 expires 中&#xff0c;当执行删除策略的时候&#xff0c;才会从 expires 中寻找对应的数据存储的地址&#xff…

React@16.x(60)Redux@4.x(9)- 实现 applyMiddleware

目录 1&#xff0c;applyMiddleware 原理2&#xff0c;实现2.1&#xff0c;applyMiddleware2.1.1&#xff0c;compose 方法2.1.2&#xff0c;applyMiddleware 2.2&#xff0c;修改 createStore 接上篇文章&#xff1a;Redux中间件介绍。 1&#xff0c;applyMiddleware 原理 R…

二、GD32F407VET6使用定时器点灯

零、所需文件及环境&#xff1a; 1、第一章建立好的LED灯闪烁程序 2、编译环境MDK5(KEIL5) 3、一个GD32F407VET6硬件 4、一个下载器j-link 或 st-link等 5.代码编辑器 Notepad &#xff08;可以不要 用记事本也能编译 都是习惯的问题&#xff09; 壹、复制LED灯闪烁程序…

Spark的动态资源分配算法

文章目录 前言基于任务需求进行资源请求的整体过程资源申请的生成过程详解资源申请的生成过程的简单例子资源调度算法的代码解析 申请资源以后的处理&#xff1a;Executor的启动或者结束对于新启动的Container的处理对于结束的Container的处理 基于资源分配结果进行任务调度Pen…