使用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;
}

猜你喜欢

转载自blog.csdn.net/qq_41790078/article/details/121695011