使用libexif开源库修改jpeg相片exif信息
libexif简介
libexif是一个开源的图片exif信息操作库,提供了对exif信息常见操作接口;
exif则是相片中的附属信息,常见的exif信息如图:
一、读exif信息
使用libexif对exif信息进行遍历,参考:https://blog.csdn.net/ibingow/article/details/7724453
二、写exif信息
说明
写exif的代码参考stackoverflow一位大佬的代码:
他的代码使用了libjpeg、libexif两个库,多封装了一些接口,可以直接设置一些exif信息,都在JpegEncoderEXIF.c
:
例:修改exif中GPS海拔高度
上述代码中,没有提供直接修改exif的接口,下面是修改海拔高度的demo,最终效果:
实现代码(Linux C):
//linux eclipse环境
#include <stdio.h>
#include <stdlib.h>
#include <libexif/exif-data.h>
#include <libjpeg/jpeg-data.h>
#include <JpegEncoderEXIF/JpegEncoderEXIF.h>
/*
* create_tag() is from the write-exif.c sample code that is floating
* around the interweb - with thanks to whoever created it!
*/
/* Create a brand-new tag with a data field of the given length, in the
* given IFD. This is needed when exif_entry_initialize() isn't able to create
* this type of tag itself, or the default data length it creates isn't the
* correct length.
*/
static ExifEntry *create_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 = buf;
entry->size = len;
entry->tag = tag;
entry->components = len;
entry->format = EXIF_FORMAT_UNDEFINED;
/* 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 main(int argc, char *argv[])
{
if(argc < 3){
fprintf(stderr, "Usage: %s <src.jpg> <out.jpg>\n", argv[0]);
return -1;
}
//1.获取jpeg、exif数据
JPEGData *pJpegData = jpeg_data_new_from_file(argv[1]);
if(!pJpegData){
printf("jpeg_data_new_from_file err\n");
return -1;
}
ExifData *pExifData = jpeg_data_get_exif_data(pJpegData);
if(!pExifData){
printf("jpeg_data_get_exif_data err\n");
return -1;
}
//2.获取对应的entry
printf("Now to get entry!************************************\n");
//获取GPS海拔信息的entry
ExifEntry *pExifEntry = exif_content_get_entry(pExifData->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_ALTITUDE);
if(!pExifEntry){
printf("exif_content_get_entry err\n");
printf("No EXIF_TAG_GPS_ALTITUDE_REF info!\n");
return -1;
}
char value_array[1024];
printf("EXIF_TAG_GPS_LATITUDE: %s\n", exif_entry_get_value(pExifEntry, value_array, sizeof(value_array)));
ExifByteOrder byte_order = exif_data_get_byte_order(pExifData);//获取图片的字节序
ExifRational altitude = {
.denominator = 10,//分母
.numerator = 666//分子
//最终写入海拔:666/10 = 66.6m
};
exif_set_rational(pExifEntry->data, byte_order, altitude);
//写入exif到jpeg
jpeg_data_set_exif_data(pJpegData, pExifData);
//jpeg另存为
if(0 == jpeg_data_save_file(pJpegData, argv[2])){
printf("jpeg_data_save_file error!\n");
return -1;
}
return 0;
}