关于jpg文件格式的一个情景-第二篇(exiv2:先学习)

 学习原文:https://blog.csdn.net/weixin_33628677/article/details/149412194 

Exiv2是一个开源的C++库与命令行工具,专注于图像元数据的管理。用户可以利用它读取、写入、删除和修改图像文件中的Exif、IPTC、XMP和ICC等元数据。Exiv2提供丰富的API接口,适合图像处理软件开发,并且支持版本控制和安全隐私考虑。它的扩展性使其能够适应未来的新元数据标准。

  Exiv2库支持多种图像格式的元数据读写操作,这包括但不限于JPEG、TIFF、PNG等常见格式。除了基本的读写功能,Exiv2还提供了高级功能,如元数据的增删改查、格式转换和图片编辑等。

Exif标准概述:

EXIF(Exchangeable Image File Format)是专为数字相机图像而设计的文件格式标准,由日本电子工业发展协会(JEIDA)于1995年提出。它能够存储图片拍摄的详细信息,如拍摄日期、时间、相机型号、曝光时间、光圈大小、ISO值、使用的闪光灯等。此外,EXIF还支持存储缩略图、图像原始数据等。

EXIF格式是JPEG、TIFF格式的一个扩展,除了包含图像数据外,还额外包含用于记录图像相关属性的元数据。这种信息对于摄影师和图片编辑者来说至关重要,因为它提供了关于拍摄环境和条件的详细背景,有助于评估图像质量和改进拍摄技术。

Exif数据读取与写入

  读取和写入Exif数据是Exiv2库的核心功能之一。在读取方面,Exiv2可以轻易地从JPEG或TIFF文件中提取出Exif信息。而写入Exif数据通常是在图片拍摄之后,需要对某些信息进行修改或添加。

以下是一个使用Exiv2库读取JPEG图片中Exif信息的示例代码:

#include <exiv2/exiv2.hpp>
 
int main() {
    Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open("example.jpg");
    image->readMetadata();
 
    Exiv2::ExifData &exifData = image->exifData();
 
    for( Exiv2::ExifData::const_iterator it = exifData.begin(); it != exifData.end(); ++it ) {
        std::cout << (*it).key() << std::endl;
        std::cout << " " << (*it).value() << std::endl;
    }
 
    return 0;
}

在写入方面,Exiv2库提供了一系列功能来修改图像的Exif信息。例如,您可以修改拍摄日期和时间,或添加特定的描述信息到图片中。下面的代码展示了如何设置一个图片的Exif标签:

#include <exiv2/exiv2.hpp>
 
int main() {
    Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open("example.jpg");
    image->readMetadata();
    Exiv2::ExifData &exifData = image->exifData();
 
    // 设置拍摄日期和时间
    exifData["Exif.Photo.DateTime"] = "2023:04:11 10:59:58";
 
    // 添加图片的描述信息
    exifData["Exif.Image.ImageDescription"] = "A beautiful sunset";
 
    image->writeMetadata();
 
    return 0;
}

在某些情况下,可能需要从图片中删除某些Exif数据,比如删除拍摄地点信息以保护隐私。Exiv2库使得删除Exif数据变得简单:

#include <exiv2/exiv2.hpp>
 
int main() {
    Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open("example.jpg");
    image->readMetadata();
 
    // 删除特定的Exif数据
    image->exifData()["Exif.Photo.DateTime"].clear();
    image->writeMetadata();
 
    return 0;
}
IPTC数据的读取与编辑

使用Exiv2读取和编辑IPTC数据的过程类似于Exif数据的处理。下面的代码展示了如何读取和设置图片的IPTC信息:

#include <exiv2/exiv2.hpp>
 
int main() {
    Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open("example.jpg");
    image->readMetadata();
 
    Exiv2::IptcData &iptcData = image->iptcData();
 
    // 打印 IPTC 数据
    for( Exiv2::IptcData::const_iterator it = iptcData.begin(); it != iptcData.end(); ++it ) {
        std::cout << (*it).key() << std::endl;
        std::cout << " " << (*it).value() << std::endl;
    }
 
    // 设置 IPTC 数据
    iptcData["Iptc.Application2.Byline"] = "John Doe";
    iptcData["Iptc.Application2.Caption"] = "This is a photo of a sunset.";
 
    image->writeMetadata();
 
    return 0;
}
XMP数据的插入与提取
#include <exiv2/exiv2.hpp>
 
int main() {
    Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open("example.jpg");
    image->readMetadata();
 
    Exiv2::XmpData &xmpData = image->xmpData();
 
    // 打印 XMP 数据
    for( Exiv2::XmpData::const_iterator it = xmpData.begin(); it != xmpData.end(); ++it ) {
        std::cout << it->key() << std::endl;
        std::cout << " " << it->value() << std::endl;
    }
 
    // 设置 XMP 数据
    xmpData["Xmp.dc.title"] = "My Photo";
    xmpData["Xmp.dc.description"] = "An example of XMP metadata";
 
    image->writeMetadata();
 
    return 0;
}

常用接口:

image

 ICC文件的读写操作

使用Exiv2库,开发者可以轻松读取和写入ICC色彩配置文件。读取ICC文件通常涉及获取ICC配置文件的头部信息和颜色表,以及了解设备特定的色彩空间和特性文件的构成。

#include <exiv2/exiv2.hpp>
 
int main() {
    Exiv2::Image::AutoPtr image = Exiv2::Image::open("image_with_icc.jpg");
    if (image.get() == nullptr) {
        std::cerr << "Cannot open image file" << std::endl;
        return -1;
    }
    Exiv2::ICCProfile::AutoPtr iccProfile = image->iccProfile();
    if (iccProfile.get() == nullptr) {
        std::cerr << "No ICC profile found in the image" << std::endl;
        return -1;
    }
 
    // Print some information about the ICC profile
    std::cout << "ICC profile size: " << iccProfile->size() << " bytes" << std::endl;
    std::cout << "ICC profile version: " << iccProfile->version() << std::endl;
    // ... (更多读取ICC文件的操作)
 
    // 写入ICC文件到另一个图像
    image->setIccProfile(iccProfile);
    image->writeFile("output_image_with_icc.jpg");
 
    return 0;
}

在上述代码中, open 函数用于打开含有ICC色彩配置文件的图片, iccProfile 用于获取图片的ICC配置文件。 size() 和 version() 方法展示了如何读取ICC配置文件的大小和版本信息。之后,使用 setIccProfile 方法将ICC配置文件写入到新的图片文件中。

 

posted @ 2025-08-05 17:03  Wind_Swing_Dunn  阅读(20)  评论(0)    收藏  举报