libexif示例在exif数据中添加一个小的Xml文档

时间:2010-01-11 21:33:57

标签: c jpeg exif libexif

任何libexif用户/开发人员可以指出我在JPG图像的exif元数据中添加小型自定义XML文档的适当调用的正确方向吗?

我一直在谷歌上搜索一段时间,但无法理解。

我对任何其他开源库都开放,只要它是基于C的,我就可以这样做。

2 个答案:

答案 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,并保留文件的其余部分。

请参阅下面的图片以获取直观说明(如果您无法阅读,只需右键单击并查看图像):

Example of XML file inserted into EXIF data of 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字符串。