使用C ++修改EXIF数据

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用C ++修改EXIF数据相关的知识,希望对你有一定的参考价值。

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

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

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

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

我尝试了很多像这样的库:

  • easyexif
  • exiv2
  • 菲尔哈维

我也试过它们:

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

我也在php上工作,但我只能读取和提取EIXF,但我不能在我的图片上写新数据。

我怎么解决这个问题?

答案

你可以使用这段代码。我使用Image::GetPropertyIdList methodReading 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 .
");

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

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

Android 逆向使用 DB Browser 查看并修改 SQLite 数据库 ( 从 Android 应用数据目录中拷贝数据库文件 | 使用 DB Browser 工具查看数据块文件 )(代码片段

Oracle 数据库 - 使用UEStudio修改dmp文件版本号,解决imp命令恢复的数据库与dmp本地文件版本号不匹配导致的导入失败问题,“ORACLE error 12547”问题处理(代码片段

C语言的使用步骤+代码的作用以及要点

使用C#中的锁定位写入映像

C语言中,如何实现从文件中读取数据(大量的数据)后,在循环体中使用,每次传递3个值到数组。

Redis