Use the libexif open source library to modify the exif information of jpeg photos

Use the libexif open source library to modify the exif information of jpeg photos

Introduction to libexif

libexif is an open source image exif information operation library, which provides a common operation interface for exif information;
exif is the auxiliary information in the photo, and the common exif information is shown in the figure:
insert image description here

1. Read exif information

Use libexif to traverse exif information, refer to: https://blog.csdn.net/ibingow/article/details/7724453

2. Write exif information

illustrate

The code for writing exif refers to the code of a big guy in stackoverflow:

His code uses two libraries, libjpeg and libexif, and encapsulates some more interfaces. You can directly set some exif information, all in JpegEncoderEXIF.c:
insert image description here

Example: Modify the GPS altitude in exif

In the above code, there is no interface for directly modifying exif. The following is a demo for modifying the altitude. The final effect:
insert image description here
implementation code (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;
}

Guess you like

Origin blog.csdn.net/qq_41790078/article/details/121695011