首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用libexif与libjpeg一起设置现有JPEG上的exif标记

使用libexif与libjpeg一起设置现有JPEG上的exif标记
EN

Stack Overflow用户
提问于 2018-01-03 12:25:09
回答 1查看 2.1K关注 0票数 3

在我的C程序中,我希望使用jpeg libexif和inputFilePath,libjpeg来设置存在于给定路径outputFilePath.的现有jpeg文件上的exif标记,并将结果保存到输出路径outputFilePath.。

输入的jpeg文件很大(40000×40000像素),所以在内存中加载整个图像是不可取的,不应该需要。

我不关心Jpeg中现有的Exif标签,它们可能会被删除。

我已经阅读并试用了libexif提供的示例,它使用固定的JPEG,但不知道如何对任何JPEG做同样的操作。

顺便说一句,我得到了下面的代码,它通过加载jpeg内存中的来设置exif标记。它使用与libexif一起提供的exif实用程序中提供的libjpeg实现。

代码语言:javascript
复制
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);
EN

回答 1

Stack Overflow用户

发布于 2018-02-15 19:28:31

如果您没有重新压缩或编辑图像,那么您将不需要libjpeg。这可以用fopenfputc来完成。

exiv2中可以很好地描述JPEG文件结构和元数据。大多数jpeg文件将从0xFFD8 (图像的开始)开始,然后是JFIF数据(0xFF E0 <length> <data>)的APP0块。如果存在EXIF头,则位于APP1块(0xFF E1 <length> <data>)中。

JPEG文件中的块被格式化为

  • 标记(0xFF xx),其中xxAPPn块的En
  • 内容
代码语言:javascript
复制
- 2 bytes - length of content in bytes **including these 2 bytes**
- data

因此,您的程序大纲将是

  1. 将文件复制到APP1
  2. APP1块代替
  3. 复制文件的其余部分

可以使用exif_data_save_data()libexif中创建EXIF标头内容。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48077371

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档