在我的C程序中,我想使用 libexif 和 libjpeg 在给定路径上存在的现有jpeg文件上设置exif标记 inputFilePath ,并将生成的jpeg保存到输出路径 outputFilePath 。
输入jpeg文件很大(40000 X 40000像素),因此将整个图像加载到内存中并不是优选的,也不应该需要。
我不关心Jpeg中的其他现有Exif标签,它们可能会被移除。
我已经阅读并尝试了libexif提供的使用固定JPEG的示例,但是无法弄清楚如何对任何JPEG执行相同操作。
顺便说一下,我确实得到了以下代码,它通过加载jpeg in-memory 来设置exif标签。它使用与libexif一起提供的exif实用程序中提供的libjpeg实现。
ExifEntry *entry;
ExifData *exif = exif_data_new();
if (!exif) {
//Out of memory
}
/* Set the image options */
exif_data_set_option(exif, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION);
exif_data_set_data_type(exif, EXIF_DATA_TYPE_COMPRESSED);
exif_data_set_byte_order(exif, FILE_BYTE_ORDER);
/* Create the mandatory EXIF fields with default data */
exif_data_fix(exif);
/* All these tags are created with default values by exif_data_fix() */
/* Change the data to the correct values for this image. */
entry = init_tag(exif, EXIF_IFD_EXIF, EXIF_TAG_PIXEL_X_DIMENSION);
exif_set_long(entry->data, FILE_BYTE_ORDER, w);
entry = init_tag(exif, EXIF_IFD_EXIF, EXIF_TAG_PIXEL_Y_DIMENSION);
exif_set_long(entry->data, FILE_BYTE_ORDER, h);
entry = init_tag(exif, EXIF_IFD_EXIF, EXIF_TAG_COLOR_SPACE);
exif_set_short(entry->data, FILE_BYTE_ORDER, 1);
/* Create a EXIF_TAG_USER_COMMENT tag. This one must be handled
* differently because that tag isn't automatically created and
* allocated by exif_data_fix(), nor can it be created using
* exif_entry_initialize() so it must be explicitly allocated here.
*/
entry = create_tag(exif, EXIF_IFD_EXIF, EXIF_TAG_USER_COMMENT,
sizeof(ASCII_COMMENT) + sizeof(FILE_COMMENT) - 2);
/* Write the special header needed for a comment tag */
memcpy(entry->data, ASCII_COMMENT, sizeof(ASCII_COMMENT) - 1);
/* Write the actual comment text, without the trailing NUL character */
memcpy(entry->data + 8, FILE_COMMENT, sizeof(FILE_COMMENT) - 1);
/* create_tag() happens to set the format and components correctly for
* EXIF_TAG_USER_COMMENT, so there is nothing more to do. */
JPEGData *jdata;
unsigned char *d = NULL;
unsigned int ds;
ExifLog *log = NULL;
/* Parse the JPEG file. */
jdata = jpeg_data_new();
jpeg_data_log(jdata, log);
jpeg_data_load_file(jdata, inputFilePath);
/* Make sure the EXIF data is not too big. */
exif_data_save_data(exif, &d, &ds);
if (ds) {
free(d);
if (ds > 0xffff)
//Too much EXIF data
};
jpeg_data_set_exif_data(jdata, exif);
/* Save the modified image. */
jpeg_data_save_file(jdata, outputFilePath);
jpeg_data_unref(jdata);
答案 0 :(得分:2)
如果您没有重新压缩或修改图片,那么您将不再需要libjpeg
。可以使用fopen
和fputc
完成此操作。
来自exiv2的JPEG文件结构和元数据的良好描述。大多数jpeg文件将以0xFFD8
(图像开头)开头,然后是JFIF数据的APP0
块(0xFF E0 <length> <data>
)。如果有EXIF标题,则会在APP1
块(0xFF E1 <length> <data>
)中显示。
JPEG文件中的块格式为
0xFF xx
)xx
En
APPn
块{/ 1}} 内容
所以,你的程序大纲将是
APP1
块APP1
块可以使用exif_data_save_data()
中的libexif
创建EXIF标题内容。