Пример libexif для добавления небольшого XML-документа в данные exif - PullRequest
3 голосов
/ 12 января 2010

Любой пользователь / разработчик libexif, который мог бы указать мне правильное направление в отношении того, как лучше всего добавить небольшой пользовательский документ XML в метаданные exif изображения JPG?

Я некоторое время гуглял и не могу понять.

Я открыт для любой другой библиотеки с открытым исходным кодом, которая позволит мне делать это, пока она основана на C.

Ответы [ 2 ]

2 голосов
/ 10 июня 2015

Вы можете встроить любые данные в блок данных EXIF ​​в формате JPG. Я не знаю ограничения по размеру, вы просто разбиваете его на несколько блоков данных EXIF, если это необходимо.

Тебе даже не нужен libexif. Вы можете сделать все это вручную в коде C, программно выполнив следующее (обратите внимание, что это работает только с файлами JPG, в которых уже есть другие данные EXIF):

Обычно ваш файл 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 и оставьте остальной файл как есть.

См. Рисунок ниже для визуального объяснения (просто щелкните правой кнопкой мыши и просмотрите изображение, если вы не можете его прочитать):

Example of XML file inserted into EXIF data of JPG

Вот мой JPG с моим фиктивным XML-файлом. Щелкните правой кнопкой мыши, сохраните, откройте его в шестнадцатеричном редакторе и посмотрите сами:

Пример JPG с XML в блоке данных EXIF ​​

В конце просто проверьте, что вы все еще можете открыть 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, но вы можете использовать любой шестнадцатеричный редактор.

0 голосов
/ 22 января 2010

Я считаю, что максимальный размер поля EXIF ​​составляет 32 КБ, поэтому этого должно быть более чем достаточно для создания файла XML.

Сгенерируйте ASCII-C-строку представления вашего XML-дерева, возможно, используя libxml2. Затем установите EXIF ​​тег «Комментарий пользователя» к этой строке.

Следующий пример устанавливает этот тег: http://libexif.cvs.sourceforge.net/viewvc/libexif/libexif/contrib/examples/write-exif.c?view=markup

Я думаю, что вам нужно использовать этот префикс ASCII_COMMENT, а FILE_COMMENT будет вашей строкой XML.

...