Samoy的小窝


一只默默工作的程序猿


欢迎光临Samoy的小屋

使用exiv2读取或者修改图片元数据

0. 前言

开发环境为Windows,使用vcpkg安装exiv2库。关于vcpkg的安装,请参考vcpkg官方文档。 如果使用其他环境,请自行通过搜索引擎查找相关资料。

1. 安装 exiv2

vcpkg install exiv2

2. CMmakeLists.txt 配置

include("C:\\vcpkg\\scripts\\buildsystems\\vcpkg.cmake") # 此处修改为你的vcpkg安装路径
find_package(exiv2 CONFIG REQUIRED)
target_link_libraries(your_target PRIVATE Exiv2::exiv2lib) # 此处的your_target请修改为你的项目名称

3. 引入头文件

#include <exiv2/exiv2.hpp>

4. 读取图片元数据

static Exiv2::ExifData::const_iterator GetExifValue(Exiv2::ExifData& ed, const std::string& key) {
	Exiv2::ExifKey tmp = Exiv2::ExifKey(key);
	Exiv2::ExifData::iterator tag = ed.findKey(tmp);
	return tag;
}

5. 修改图片元数据

static bool SetExifValue(Exiv2::ExifData& ed, const std::string& key, const std::string& value) {
	Exiv2::ExifKey tmp = Exiv2::ExifKey(key);
	Exiv2::ExifData::iterator tag = ed.findKey(tmp);
	if (tag != ed.end()) {
		return tag->setValue(value) == 0;
	}
	return false;
}

6. 完整代码

#include <exiv2/exiv2.hpp>
#include <iostream>


// 获取exif数据
static Exiv2::ExifData::const_iterator GetExifValue(Exiv2::ExifData& ed, const std::string& key) {
	Exiv2::ExifKey tmp = Exiv2::ExifKey(key);
	Exiv2::ExifData::iterator tag = ed.findKey(tmp);
	return tag;
}

// 修改exif数据
static bool SetExifValue(Exiv2::ExifData& ed, const std::string& key, const std::string& value) {
	Exiv2::ExifKey tmp = Exiv2::ExifKey(key);
	Exiv2::ExifData::iterator tag = ed.findKey(tmp);
	if (tag != ed.end()) {
		return tag->setValue(value) == 0;
	}
	return false;
}

int main() {
	try {
		// 打开图片文件
		std::string imagePath = "E:\\Projects\\Demo\\test.JPG";  // Replace with the actual image path
		std::unique_ptr<Exiv2::Image> image = Exiv2::ImageFactory::open(imagePath);

		if (image.get() == 0) {
			std::cerr << "Failed to open the image" << std::endl;
			return EXIT_FAILURE;
		}


		// 获取exif数据
		image->readMetadata();
		Exiv2::ExifData& exifData = image->exifData();

		// 修改exif数据
		bool result = SetExifValue(exifData, "Exif.Image.Make", "Demo");
		if (result) {
			// 保存修改
			image->setExifData(exifData);
			image->writeMetadata();
		}
		else {
			std::cout << "Failed to modify Exif.Image.Make" << std::endl;
		}

		// 遍历exif数据,打印所有的key和value
		for (Exiv2::ExifData::const_iterator it = exifData.begin(); it != exifData.end(); ++it) {
			std::cout << it->key() << " : " << it->value() << std::endl;
		}
	}
	catch (Exiv2::Error& ex) {
		std::cerr << "Caught Exiv2 exception: " << ex << std::endl;
		return EXIT_FAILURE;
	}

	return EXIT_SUCCESS;
}
欢迎在评论区留下您的见解~
最近的文章

React深入理解

React自从 React 16 版本引入 Fiber 架构后,渲染过程变得更加精细和可控。整个更新流程主要可以分为三个关键模块:Scheduler(调度器)、Reconciler(协调器) 和 Renderer(渲染器)。关键模块Scheduler(调度器) 调度器是React内部的一个核心模块,它负责决定何时以及如何执行更新任务。在React应用中,当状态发生变化时,会触发重新渲染,而调度器的作用就是根据任务优先级将这些更新任务排队。 Scheduler 遵循可...…

Web
更早的文章

Typescript装饰器简介(下)

在上一篇文章中,我们介绍了装饰器的基本概念,并通过一个简单的例子来展示了装饰器的使用方法。然后,Typescript同时支持装饰器的新语法和旧语法。本文来介绍Typescript的旧语法。在本文中,所使用的语法均为旧语法。1.装饰器配置如果通过旧语法使用装饰器,需要在tsconfig.json中配置compilerOptions.experimentalDecorators为true。{ "compilerOptions": { "experimentalDecorators": ...…

Web