博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
jpeg exif
阅读量:6598 次
发布时间:2019-06-24

本文共 6872 字,大约阅读时间需要 22 分钟。

公司项目需要在jpeg图片里面添加exif信息,同事完成了这部分代码;但是有些手机兼容性有问题;

libexif 地址:http://libexif.sourceforge.net/

注意相关资料来之:

http://blog.csdn.net/fioletfly/article/details/53605959

注意使用的工具为:PowerExif.exe,因为项目太多了,需要对比添加~有工具可以比较好的参考.

手机兼容有问题,注意是因为一些项目没按照exif标准来添加;按标准来添加,添加后用PowerExif.exe解析,如果每项都正常了,基本手机解析不会有问题;

 

代码如下:

1.前面代码来至src sample下面的;

2.添加了一些必要的exif信息;

3.添加到结果如最后.

static const unsigned char exif_header[] = {  0xff, 0xd8, 0xff, 0xe1,};/* length of data in exif_header */static const unsigned int exif_header_len = sizeof(exif_header);/* length of data in image_jpg */static const unsigned int image_jpg_len ;//= sizeof(image_jpg);/* start of JPEG image data section */static const unsigned int image_data_offset = 20;#define image_data_len (image_jpg_len - image_data_offset)const char *pucMaker = "xx公司";const char *pucModel = "拍照设备";/* 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();    assert(mem != NULL); /* catch an out of memory condition */    /* Create a new ExifEntry using our allocator */    entry = exif_entry_new_mem (mem);    assert(entry != NULL);    /* Allocate memory to use for holding the tag data */    buf = exif_mem_alloc(mem, len);    assert(buf != NULL);    /* 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;}//需要参考PowerExif.exe软件打开图片//添加对应的只需要对应的代码ID,exifname、数据类型、和数据长度;int cdr_write_exif_to_jpg(char *pSrcFileName, GPS_INFO sGpsInfo){        int rc = 1;    char GPSversionid[5]={
0x02,0x02,0x00,0x00,0x00}; FILE *f = NULL; unsigned char *exif_data; unsigned int exif_data_len; FILE *f2 = fopen(pSrcFileName, "r"); if (!f2) { fprintf(stderr, "Error creating file \n"); return -1; } fseek (f2, 0, SEEK_END); ///将文件指针移动文件结尾 int iFileSize = ftell (f2); ///求出当前文件指针距离文件开始的字节数 fseek (f2, 0, SEEK_SET); char *buf = calloc(iFileSize,sizeof(char)); if(buf == NULL){ printf("calloc fails!\n"); fclose(f2); return -1; } int i = 0; int pos = 0; char temp = 0; for(i=0; i
format = EXIF_FORMAT_BYTE; entry->components = 4; exif_set_sshort(entry->data, FILE_BYTE_ORDER, GPSversionid[0]); exif_set_sshort(entry->data+1, FILE_BYTE_ORDER, GPSversionid[1]); exif_set_sshort(entry->data+2, FILE_BYTE_ORDER, GPSversionid[2]); exif_set_sshort(entry->data+3, FILE_BYTE_ORDER, GPSversionid[3]); entry = create_tag(exif, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE_REF,2); entry->format = EXIF_FORMAT_ASCII; memcpy(entry->data, "N", 2); ExifRational a; ExifRational b; ExifRational c; a.numerator = sGpsInfo.latitude_Degree;//纬度 a.denominator = 1; b.numerator = sGpsInfo.latitude_Cent; b.denominator = 1; c.numerator = sGpsInfo.latitude_Second; c.denominator = 1; entry = create_tag(exif, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE,24); entry->format = EXIF_FORMAT_RATIONAL; entry->components = 3; exif_set_rational(entry->data,FILE_BYTE_ORDER,a); exif_set_rational(entry->data+8,FILE_BYTE_ORDER,b); exif_set_rational(entry->data+16,FILE_BYTE_ORDER,c); entry = create_tag(exif, EXIF_IFD_GPS, EXIF_TAG_GPS_LONGITUDE_REF,2); entry->format = EXIF_FORMAT_ASCII; entry->components = 2; memcpy(entry->data, "E", 2); a.numerator = sGpsInfo.longitude_Degree; a.denominator = 1; b.numerator = sGpsInfo.longitude_Cent; b.denominator = 1; c.numerator = sGpsInfo.longitude_Second; c.denominator = 1; entry = create_tag(exif, EXIF_IFD_GPS, EXIF_TAG_GPS_LONGITUDE,24); entry->format = EXIF_FORMAT_RATIONAL; entry->components = 3; exif_set_rational(entry->data,FILE_BYTE_ORDER,a); exif_set_rational(entry->data+8,FILE_BYTE_ORDER,b); exif_set_rational(entry->data+16,FILE_BYTE_ORDER,c); //GPS速度单位K KM/H entry = create_tag(exif, EXIF_IFD_GPS, EXIF_TAG_GPS_SPEED_REF,2); entry->format = EXIF_FORMAT_ASCII; //entry->components = 1; memcpy(entry->data, "K", 2); //GPS速度值. entry = create_tag(exif, EXIF_IFD_GPS, EXIF_TAG_GPS_SPEED,8); entry->format = EXIF_FORMAT_RATIONAL; entry->components = 1; a.numerator = sGpsInfo.speed; a.denominator = 1; exif_set_rational(entry->data,FILE_BYTE_ORDER,a); /*date time*/ entry = create_tag(exif, EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_ORIGINAL,20); entry->format = EXIF_FORMAT_ASCII; //entry->components = 20; char pDataTime[21] = {
0}; sprintf(pDataTime,"%04d-%02d-%02d %02d:%02d:%02d",sGpsInfo.D.year,sGpsInfo.D.month,sGpsInfo.D.day, sGpsInfo.D.hour,sGpsInfo.D.minute,sGpsInfo.D.second); memcpy(entry->data,pDataTime,20); //厂商信息和设备信息 entry = create_tag(exif, EXIF_IFD_0, EXIF_TAG_MAKE,strlen(pucMaker)+1); entry->format = EXIF_FORMAT_ASCII; memcpy(entry->data,pucMaker,strlen(pucMaker)); entry = create_tag(exif, EXIF_IFD_0, EXIF_TAG_MODEL,strlen(pucModel)+1); entry->format = EXIF_FORMAT_ASCII; memcpy(entry->data,pucModel,strlen(pucModel)); exif_data_save_data(exif, &exif_data, &exif_data_len); assert(exif_data != NULL); f = fopen(pSrcFileName, "wb");//write exif to this file pSrcFileName if (!f) { exif_data_unref(exif); free(buf); buf=NULL; return rc; } /* Write EXIF header */ if (fwrite(exif_header, exif_header_len, 1, f) != 1) {goto errout; } /* Write EXIF block length in big-endian order */ if (fputc((exif_data_len+2) >> 8, f) < 0) {goto errout; } if (fputc((exif_data_len+2) & 0xff, f) < 0) {goto errout; } /* Write EXIF data block */ if (fwrite(exif_data, exif_data_len, 1, f) != 1) {goto errout; } int image_data_len2 = iFileSize - image_data_offset; /* Write JPEG image data, skipping the non-EXIF header */ if (fwrite(buf+image_data_offset, image_data_len2, 1, f) != 1) {goto errout; } rc = 0; free(buf); buf = NULL; fflush(f);errout: if (fclose(f)) { fprintf(stderr, "Error writing to file %s\n", FILE_NAME); rc = 1; } /* The allocator we're using for ExifData is the standard one, so use * it directly to free this pointer. */ free(exif_data); exif_data_unref(exif); return rc;}

 

添加后的图片效果如下:

 

转载于:https://www.cnblogs.com/streammm/p/6599241.html

你可能感兴趣的文章
《从零开始学Swift》学习笔记(Day 35)——会使用下标吗?
查看>>
DNSmasq
查看>>
j2ee四大作用域pagecontext,request,session,ServletContex
查看>>
httpd.conf的基本设置
查看>>
php socket通信机制实例说明与代码
查看>>
Java 编程学习(四) 重载/传参/构造器
查看>>
读一本跟技术无关的书籍
查看>>
lamp(三)php,mysql 配置
查看>>
RHEL/Centos7新功能
查看>>
phpmyadmin登录报错外加linux下修改mysql登录密码
查看>>
Drupal 7 数据库 操作
查看>>
第一部分 思科九年 一(1)
查看>>
Android findViewById返回NULL的问题
查看>>
DBA日常工作职责
查看>>
Redis的持久化
查看>>
phpMyAdmin数据库出现中文乱码
查看>>
linux安装NFS服务器学习
查看>>
Planner .NET日历日程控件能给你的应用程序提供多种日历日程功能
查看>>
我的友情链接
查看>>
word导出(使用freemarker模板导出)
查看>>