任何可以为我指明正确方向的 libexif 用户/开发人员在 JPG 图像的 exif 元数据中添加小型自定义 XML 文档的适当调用是什么?
我已经在谷歌上搜索了一段时间,无法弄清楚。
我对任何其他允许我这样做的开源库持开放态度,只要它是基于 C 的。
您可以将任何数据嵌入到 JPG 中的 EXIF 数据块中。我知道没有大小限制,如果需要,您只需将其拆分为多个 EXIF 数据块。
你甚至不需要 libexif。您可以通过以编程方式执行以下操作,在 C 代码中手动完成所有操作(请注意,这仅适用于其中已经包含其他 EXIF 数据的 JPG 文件):
基本上,您的 JPG 文件(如果其中已经有 EXIF 标头)将以以下内容开头:
0xFF 0xD8
然后第一个 Exif 标头将以此开头:
0xFF 0xE0
接下来是 Exif 数据块的长度,这里是两个字节:
0x00 0x10 //In this case it is 16 bytes (0x0010) long and it INCLUDES these two bytes of the header
接下来是 Exif 数据块的实际数据(您的可能不同)。请注意,它是 14 字节长(或 14+ 2 = 16 字节,或 0x0010,如上所示):
0x4A 0x46 0x49 0x46 0x00 0x01 0x01 0x01 0x00 0x60 0x00 0x60 0x00 0x00
现在您可以在此标头之后插入您的 XML Exif 数据块,并以 exif 数据标识符开头(始终相同):
0xFF 0xE1
然后是您的 XML 文件的大小(以字节为单位)+2 (请注意,如果您的文件的大小大于 0xFFFE,那么您必须将其拆分为多个 EXIF 数据块):
0x07 0x7D //In this case it is 1917bytes long or 0x077D
然后此时将您的 xml 直接插入到 JPG 中,并将文件的其余部分保持原样。
看下图有直观的解释(看不懂的直接右击查看图片):
这是我的 JPG,其中包含我的虚拟 XML 文件。右键单击,保存,在十六进制编辑器中打开它并自己寻找:
最后检查您是否仍然可以打开 JPG,如果可以,您就成功了。
这是 C++ 中的一个简单示例(注意我没有调试代码,只是从内存中编写的,所以请注意!):
char yourdata[]="<xml> contents to </add>";
long yourdatalen = 0x18;
//open file
char * file;
long filelen=0;
std::ifstream infile;
infile.open("yourjpg.jpg",std::ios::binary| std::ios::in);
//find size of file
infile.seekg (0, ios::end);
filelen = infile.tellg();
infile.seekg (0, ios::beg);
//read contents of file
file = new char [filelen];
infile.read(file,filelen);
infile.close();
//lets parse through the file and find any exif headers
long x=0;
if ((file[0]==0xFF) && (file[1]==0xD8)){
//all good lets go!!
while ((file[x]!=0xFF) && (file[x+1]!=0xE1)) {
x++;
}
//were at the first EXIF data block! insert XML here
char * temp=file;
file = new char [filelen+yourdatalen+4];
memcpy(file,temp,x);
file[x+0]=0xFF;
file[x+1]=0xE1;
file[x+2]=int((yourdatalen+2)/0xFF); //note assumes that your xml file is less than 0xFFFE bytes long
file[x+3]=yourdatalen-int((yourdatalen+2)/0xFF);
memcpy(&file[x+4],yourdata,yourdatalen);
memcpy(&file[x+4+yourdatalen],temp[x],filelen-x);
delete [] temp;
//Save to file
std::ofstream ofile;
ofile.open("savejpg.jpg",std::ios::binary| std::ios::out);
ofile.write(file,yourdatalen+4+filelen);
ofile.close();
}
else {
//JPG file does not have exif data in it, you'll need to add it first or find another way of adding your data
}
//Clean up
delete [] file;
我使用了 HxD,但您可以使用任何十六进制编辑器。
我相信最大的 EXIF 字段大小是 32KB,所以这对于生成 XML 文件应该绰绰有余。
生成 XML 树的 ASCII C 字符串表示,可能使用 libxml2。然后将 EXIF“用户评论”标签设置为该字符串。
以下示例设置此标记:http ://libexif.cvs.sourceforge.net/viewvc/libexif/libexif/contrib/examples/write-exif.c?view=markup
我认为您需要使用该 ASCII_COMMENT 前缀,而 FILE_COMMENT 将是您的 XML 字符串。