使用 C++ 修改 EXIF 数据

Posted

技术标签:

【中文标题】使用 C++ 修改 EXIF 数据【英文标题】:Modify EXIF Data using C++ 【发布时间】:2016-07-19 03:52:40 【问题描述】:

我们正在为比赛建造一个四旋翼机器人,其中一个要求是我们必须使用安装在四旋翼上的相机拍摄照片。

我编写了一个简单的 OpenCV 程序,它能够以 .jpg 格式捕获它们,但我的相机或我的程序无法将“纬度”和“经度”作为 EXIF 保存在我的图像上。

我为我的机器人添加了一个 GPS 模块,该模块可以在拍摄照片时检索 GPS 数据并将它们保存到文本文件中。

所以我的主要问题是在捕获图片时将这些数据从文本文件中分别添加到图片中。

我尝试了很多库,例如:

easyexif Exiv2 菲尔·哈维

我也试过了:

Visual C++ .net 2015 开发 C++ (GCC) 代码块 (GCC)

我还研究过 php,但我只能读取和提取 EIXF,但不能在我的图片上写入新数据。

我该如何解决这个问题?

【问题讨论】:

我尝试了很多库,例如:- easyexif - Exiv2 和 Phil Harvey -- 这些库有什么问题? 你要处理的图片是什么格式的? 您好,亲爱的 Paul,图片为 .jpg 格式。 此链接有一个关于使用 exiv2 向图像添加数据的完整示例:exiv2 example 非常感谢,但我不知道示例 2:addmoddel.cpp 我的图像在哪里需要修改? 【参考方案1】:

您可以使用此代码。我使用Image::GetPropertyIdList method 和Reading and Writing Metadata 作为此代码的材料。不幸的是,我在 opencv 中没有找到任何可以操作 Exif 的函数。

 #include <windows.h>
 #include <gdiplus.h>
 #include <stdio.h>
 #include <Math.h>
 #pragma comment(lib,"gdiplus.lib")
 using namespace Gdiplus;


 int GetEncoderClsid(const WCHAR* format, CLSID* pClsid) //i copy this function from Doc.microsoft.com
 
UINT  num = 0;          // number of image encoders
UINT  size = 0;         // size of the image encoder array in bytes

ImageCodecInfo* pImageCodecInfo = NULL;

GetImageEncodersSize(&num, &size);
if (size == 0)
    return -1;  // Failure

pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
if (pImageCodecInfo == NULL)
    return -1;  // Failure

GetImageEncoders(num, size, pImageCodecInfo);

for (UINT j = 0; j < num; ++j)

    if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0)
    
        *pClsid = pImageCodecInfo[j].Clsid;
        free(pImageCodecInfo);
        return j;  // Success
    


free(pImageCodecInfo);
return -1; 


int main()
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
Status stat;
CLSID  clsid;

Bitmap* bitmap = new Bitmap(L"Source.bmp"); // you can use any Image Format as Source 
PropertyItem* propertyItem = new PropertyItem;
// Get the CLSID of the JPEG encoder.
GetEncoderClsid(L"image/jpeg", &clsid);

double dlan = 35.715298; // we supposed that your GPS data is Double if its not skip this step
// convert double to unsigned long array
double coord = dlan;
int sec = (int)round(coord * 3600);
int deg = sec / 3600;
sec = abs(sec % 3600);
int min = sec / 60;
sec %= 60;
unsigned long ulExifCoordFormatLan[6] =  deg, 1, min, 1, sec, 1 ;
propertyItem->id = PropertyTagGpsLatitude;
propertyItem->length = sizeof(long) * 2 * 3;
propertyItem->type = PropertyTagTypeRational;
propertyItem->value = ulExifCoordFormatLan;
Status s = bitmap->SetPropertyItem(propertyItem);// saving image to the destination

stat = bitmap->Save(L"Dest.jpg", &clsid, NULL);
if (s == Ok && stat==Ok)
    printf("Dest.jpg saved successfully .\n");

delete propertyItem;
delete bitmap;
GdiplusShutdown(gdiplusToken);
return 0;

【讨论】:

以上是关于使用 C++ 修改 EXIF 数据的主要内容,如果未能解决你的问题,请参考以下文章

如何在不加载图像的情况下为文件系统上的现有图像写入或修改 EXIF 数据?

Python 批量修改图片exif属性

Swift如何修改从移动相机拍摄的图像中的exif信息

python 用于将图像创建和修改日期更新为EXIF日期的Python脚本。

更改EXIF数据以进行正确的iPhone识别

纯净软件三款照片EXIF信息删除软件 Clear ExifJPEG & PNG StripperEasy Exif Delete 非专业横向对比