libexif:使用IPTC/XMP将新的exif写入映像 [英] libexif: writing new exif into image with IPTC/XMP

查看:267
本文介绍了libexif:使用IPTC/XMP将新的exif写入映像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用libexif将EXIF元数据写入JPEG图像.我遇到了没有EXIF但带有IPTC/XMP元数据的图像的问题.使用IPTC/XMP将EXIF写入图像后,我无法读取EXIF."exif"命令行实用程序(也使用libexif)报告EXIF损坏.如果我对没有任何元数据的图像执行相同的操作,则一切正常.

I am trying to write EXIF metadata to JPEG images using libexif. I've faced with problem with images without EXIF but with IPTC/XMP metadata. After writing EXIF to images with IPTC/XMP I can't read EXIF. The "exif" command line utility (which also use libexif) report EXIF corruption. If I do the same for images without any metadata everything works fine.

这是一个演示问题的小型测试应用程序(它假定我们正在使用没有EXIF的图像).

Here is small test application which demonstrates issue (it assume that we are working with image without EXIF).

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

#include <libexif/exif-data.h>
#include <libexif/exif-loader.h>
#include <jpeglib.h>

#include "jpegexif/jpeg-data.h"
#include "jpegexif/jpeg-marker.h"
#include "jpegexif/jpeg-data.c"
#include "jpegexif/jpeg-marker.c"



static ExifEntry *create_ascii_tag(ExifData *exif, ExifIfd ifd, ExifTag tag, size_t len) {
    void *buf;
    ExifEntry *entry;

    // Create a memory allocator to manage this ExifEntry.
    ExifMem *mem = exif_mem_new_default();

    // Create a new ExifEntry using our allocator.
    entry = exif_entry_new_mem(mem);

    // Allocate memory to use for holding the tag data.
    buf = exif_mem_alloc(mem, len);

    // Fill in the entry.
    entry->data = (unsigned char*) buf;
    entry->size = len;
    entry->tag = tag;
    entry->components = len;
    entry->format = EXIF_FORMAT_ASCII;

    // Attach the ExifEntry to an IFD.
    exif_content_add_entry(exif->ifd[ifd], entry);

    // The ExifMem and ExifEntry are now owned elsewhere.
    exif_mem_unref(mem);
    exif_entry_unref(entry);

    return entry;
}



int create_exif_and_set_software(const char* const filename, const char* const tagvalue) {
    // For simplification we assume here that file has no EXIF, so we create new.
    ExifData* exif = exif_data_new();
    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, EXIF_BYTE_ORDER_INTEL);
    exif_data_fix(exif);

    // Create entry for "Software" and set it's data.
    ExifEntry* entry = create_ascii_tag(exif, EXIF_IFD_0, EXIF_TAG_SOFTWARE, strlen(tagvalue) + 1);
    memcpy(entry->data, tagvalue, strlen(tagvalue) + 1);

    // Write exif to JPEG.
    JPEGData* image = jpeg_data_new_from_file(filename);
    jpeg_data_set_exif_data(image, exif);
    jpeg_data_save_file(image, filename);

    // Unreference exif.
    exif_data_unref(exif);
    return 0;
}


int main(int argc, char ** argv) {
    char* filename = argv[1];

    // Create EXIF, set software and write EXIF to file.
    create_exif_and_set_software(filename, "Awesome image editor.");

    // Check that EXIF exists in file.
    ExifData* exif = exif_data_new_from_file(filename);
    printf("EXIF exists: %d\n", exif != NULL);

    return 0;
}

在这里您可以下载项目和示例图像.我使用以下命令在通过macports安装的libexif的Mac上构建它:gcc exif.c -I/opt/local/include -L/opt/local/lib -lexif

Here you could download project and sample images. I used the following command to build it on mac with libexif installed via macports: gcc exif.c -I/opt/local/include -L/opt/local/lib -lexif

推荐答案

最简单的方法是从头开始编写JPEG:首先,写入没有APP1部分的JPEG,然后添加Exif部分,然后添加所有其他XMP APP1部分.

The easy way, is to start writing the JPEG from scratch: First, write the JPEG with no APP1 sections, than add Exif section, than add all other XMP APP1 sections.

请注意,应适当更新IFD偏移量.

Note that IFD offsets should be updated appropriately.

这篇关于libexif:使用IPTC/XMP将新的exif写入映像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆