任何libexif用户/开发人员可以指出我在JPG图像的exif元数据中添加小型自定义XML文档的适当调用的正确方向吗?
我一直在谷歌上搜索一段时间,但无法理解。
我对任何其他开源库都开放,只要它是基于C的,我就可以这样做。
答案 0 :(得分:2)
您可以将任何数据嵌入到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 = 16bytes,或者如上所示为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文件。右键单击,保存,在十六进制编辑器中打开它并查找自己:
Sample JPG with XML in EXIF data block
最后检查你仍然可以打开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但您可以使用任何十六进制编辑器。
答案 1 :(得分:0)
我认为最大EXIF字段大小为32KB,因此这对于执行XML文件来说应该足够了。
使用libxml2生成XML树的ASCII C字符串表示。然后将EXIF“User Comment”标记设置为该字符串。
以下示例设置此标记:http://libexif.cvs.sourceforge.net/viewvc/libexif/libexif/contrib/examples/write-exif.c?view=markup
我认为您需要使用该ASCII_COMMENT前缀,而FILE_COMMENT将是您的XML字符串。