在jpg图片添加Exif信息的C程序实现

测试环境:Linux Fedora16 +Windows
打开图片的工具:UltraEdit
截图工具:FSCaptrue

源码下载:https://download.csdn.net/download/psy6653/10291445
写Exif信息前,图片的相关数据,以下是图片开始的数据排布;
这里写图片描述
图片以0xFF 0xD8开始,0xFF 0xE0就是图片下一个数据块开始的标示,0x00 0x10表示该数据块的长度,长度包括标示(0xFF 0xE0)2个字节;
以下是图片结束的数据排布,注意,从0开始算结束地址为0x0003515c,但数据大小是0x0003515d个字节
这里写图片描述
根据我们程序的打印信息,可知
写入的Exif信息数据大小:1162个字节_十六进制:0x48a
原始图片数据的大小:(217435+2)个字节(开始的0xFF 0xD8的2个字节)__十六进制:0x3515d
输出图片数据大小:(218597+2)个字节(开始的0xFF 0xD8的2个字节)__十六进制:0x355e7
0x48a + 0x3515d = 0x355e7
这里写图片描述
在JPG图片写数据开始的位置:
这里写图片描述
在JPG图片写数据结束的位置:
这里写图片描述
结束的地址为0x000048b,写入数据的大小0x000048b-2+1=0x48a;减去0xFF 0xD8两个字节,地址从0开始计算,所以写入数据的总大小还要加1;后面0xFF 0xE0开始的数据就是图片原始的数据;
在JPG图片结束的位置:
这里写图片描述
与程序计算的一致;
效果如下:
写入数据之前,Windows解析图片的效果如下:
这里写图片描述这里写图片描述
写入数据后,Windows解析图片的效果如下:
这里写图片描述这里写图片描述
当然也可以写入自己构造的数据,用VC编写软件把数据按自己的构造的格式解析出来(PC报告软件的制作);

如果exif信息的数据量太大,就需要分块写入,并需要区分不同块的数据。如果需要源码,可以用我在本平台上传的资源(https://download.csdn.net/download/psy6653/10291445),JPEG的Exif信息读写的C语言实现,文件其中包含

————-1.将缓冲区数据添加到JPEG图片中
————-2.将JPEG图片X数据提取到缓冲区中
————-3.将文件里的数据添加到JPEG图片中
————-4.将JPEG图片X数据提取出来,生成新的数据文件
————-5.将缓冲区里的数据添加到JPEG图片中,生成新的JPEGX图片
————-6.将文件里的数据添加到JPEG图片中,生成新的JPEGX图片

以下是本案例的源码,exif信息有冗余的自己可以修改;
程序代码

#ifndef __EXIFPARAM_H__
#define __EXIFPARAM_H__
#endif
typedef unsigned char   UCHAR;
typedef unsigned long   ULONG;
typedef unsigned int    UINT;
typedef unsigned long   DWORD;
typedef unsigned int    UINT32;
typedef int             INT32;
typedef unsigned char   UINT8;
typedef enum {
  FALSE, TRUE} BOOL;


typedef struct tagExifFileInfo
{
        char    Make[32];
        char    Model[32];
        char    Version[32];
        char    DateTime[32];
        char    CopyRight[32];

        UINT    Height;
        UINT    Width;
        UINT    Orientation;
        UINT    ColorSpace;
        UINT    Process;
        UINT    Flash;

        UINT    FocalLengthNum;
        UINT    FocalLengthDen;

        UINT    ExposureTimeNum;
        UINT    ExposureTimeDen;

        UINT    FNumberNum;
        UINT    FNumberDen;

        UINT    ApertureFNumber;

        int             SubjectDistanceNum;
        int             SubjectDistanceDen;

        UINT    CCDWidth;

        int             ExposureBiasNum;
        int             ExposureBiasDen;


        int             WhiteBalance;

        UINT    MeteringMode;

        int             ExposureProgram;

        UINT    ISOSpeedRatings[2];

        UINT    FocalPlaneXResolutionNum;
        UINT    FocalPlaneXResolutionDen;

        UINT    FocalPlaneYResolutionNum;
        UINT    FocalPlaneYResolutionDen;

        UINT    FocalPlaneResolutionUnit;

        UINT    XResolutionNum;
        UINT    XResolutionDen;
        UINT    YResolutionNum;
        UINT    YResolutionDen;
        UINT    RUnit;

        int             BrightnessNum;
        int             BrightnessDen;

        char    UserComments[150];
        UCHAR   GpsLatitudeRef;         
        UCHAR   GpsLatitude[20];                
        UCHAR   GpsLongitudeRef;        
        UCHAR   GpsLongitude[20];               
        UCHAR   GpsAltitude[10];                

}ExifFileInfo;

makeExif.c


#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h> 
#include <math.h>
#include <assert.h>
#include "exifparam.h"

#define IN
#define OUT 
#define UCHAR unsigned char
#define SATIR
#define EXIF_FILE_SIZE                          28800
#define MAX_JPG_THUMBNAIL_WIDTH         320
#define MAX_JPG_THUMBNAIL_HEIGHT        240
#define MAX_FILE_THUMB_SIZE                     (MAX_JPG_THUMBNAIL_WIDTH * MAX_JPG_THUMBNAIL_HEIGHT)

static const int APP1HeaderLen = 0x0C;
static UCHAR APP1Marker[] = {
  0xFF, 0xE1};
static UCHAR SATTag[] = {
  'S', 'A', 'T', 'I', 'R', 0x0};
static UCHAR MAX_APP1_LEN[] = {
  0xFF, 0xFE};
static const int MAX_DATA_LEN = 0xFFF4;

UCHAR ExifHeader[6]=
{
        0x45,0x78,0x69,0x66,0x00,0x00
};

UCHAR TIFFHeader[8]=
{
        0x49,0x49,0x2A,0x00,0x08,0x00,0x00,0x00
};

typedef union BytesOfShort
{
        UCHAR b[2];
        unsigned short s;
} BytesOfShort_t;


enum EXTRACT_DATE_JOB_STATE{
        EXTRACT_START=0,
        READ_EXIF_HEADER=1,
        READ_CHECK_SAT_HEADER,
        COPY_REMAINING_DATA,
        EXTRACT_END
};


static int makeExifFile ( char *ExifOut, UINT *totalLen ,ExifFileInfo *exifFileInfo)
{
    UCHAR *ExifInitialCount;
    UCHAR *tempExif = ( UCHAR * ) ExifOut;
    INT32 ExifSize;
    UINT santemp;
    UCHAR * startoftiff;
    UCHAR * IFD1OffsetAddress;
    UCHAR APP1Marker[2]=    {
  0xff,0xe1};
    UCHAR ExifLen[4]={
  0};
    UCHAR Nentries[2]={
  8,0};
    UCHAR SubIFDNentries[2]={
  18,0};
    UCHAR IFD1Nentries[2]={
  6,0};
    UCHAR EndOfEntry[4]={
  0};

    //VARIABLES FOR THE MAKE OF THE CAMERA
    UCHAR  maketag[2]={
  0xf,0x1};
    UCHAR  makeformat[2]={
  0x2,0x0};
    UCHAR  Ncomponent[4]={
  32,0x0,0x0,0x0};
    char  make[32];
    UCHAR makeoffchar[4];
    UCHAR * offset;

    //VARIABLES FOR THE MODEL OF THE CAMERA
    UCHAR  modeltag[2]={
  0x10,0x1};
    UCHAR  modelformat[2]={
  0x2,0x0};
    UCHAR  NcomponentModel[4]={
  32,0x0,0x0,0x0};
    char  model[32];
    UCHAR modeloffchar[4];

    //VARIABLES FOR THE ORIENTATION OF THE CAMERA
    UCHAR  orientationtag[2]={
  0x12,0x1};
    UCHAR  orientationformat[2]={
  0x3,0x0};
    UCHAR  NcomponentOrientation[4]={
  0x1,0x0,0x0,0x0};
    UINT  Orientation[1];
    UCHAR  Orient[4] = {
  0};


    //VARIABLES FOR THE JPEG PROCESS
    UCHAR  Processtag[2]={
  0x00,0x02};
    UCHAR  Processformat[2]={
  0x3,0x0};
    UCHAR  NcomponentProcess[4]={
  0x1,0x0,0x0,0x0};
    UINT  Process[1];
    UCHAR  Proc[4] = {
  0};

    //VARIABLES FOR THE X-RESOLUTION OF THE IMAGE
    UCHAR  XResolutiontag[2]={
  0x1A,0x1};
    UCHAR  XResolutionformat[2]={
  0x5,0x0};
    UCHAR  NcomponentXResolution[4]={
  0x1,0x0,0x0,0x0};
    UINT  XResolutionNum[1];//={0x00000048};
    UINT  XResolutionDen[1];//={0x00000001};

    UCHAR XResolutionoffchar[4];
    UCHAR XResolutionNumChar[4];
    UCHAR XResolutionDenChar[4];

    //VARIABLES FOR THE Y-RESOLUTION OF THE IMAGE
    UCHAR  YResolutiontag[2]={
  0x1B,0x1};
    UCHAR  YResolutionformat[2]={
  0x5,0x0};
    UCHAR  NcomponentYResolution[4]={
  0x1,0x0,0x0,0x0};
    UINT  YResolutionNum[1];//={0x00000048};
    UINT  YResolutionDen[1];//={0x00000001};

    UCHAR YResolutionoffchar[4];
    UCHAR YResolutionNumChar[4];
    UCHAR YResolutionDenChar[4];

    //VARIABLES FOR THE RESOLUTION UNIT OF THE CAMERA
    UCHAR  RUnittag[2]={
  0x28,0x1};
    UCHAR  RUnitformat[2]={
  0x3,0x0};
    UCHAR  NcomponentRUnit[4]={
  0x1,0x0,0x0,0x0};
    UINT  RUnit[1];
    UCHAR  RUnitChar[4] = {
  0};


    //VARIABLES FOR THE VERSION NO OF THE SOFTWARE
    UCHAR  Versiontag[2]={
  0x31,0x1};
    UCHAR  Versionformat[2]={
  0x2,0x0};
    UCHAR  NcomponentVersion[4]={
  32,0x0,0x0,0x0};
    char  Version[32];//="version 1.2";
    UCHAR Versionoffchar[4];

    //VARIABLES FOR THE DATE/TIME
    UCHAR  DateTimetag[2]={
  0x32,0x1};
    UCHAR  DateTimeformat[2]={
  0x2,0x0};
    UCHAR  NcomponentDateTime[4]={
  20,0,0,0};
    UCHAR  DateTime[32];//="2006:6:09 15:17:32";
    char  DateTimeClose[1]={
  0};
    UCHAR DateTimeoffchar[4];

    //VARIABLES FOR THE COPYRIGHT
    UCHAR  CopyRighttag[2]={
  0x98,0x82};
    UCHAR  CopyRightformat[2]={
  0x2,0x0};
    UCHAR  NcomponentCopyRight[4]={
  32,0x0,0x0,0x0};
    char  CopyRight[32];
    UCHAR CopyRightoffchar[4];

    //VARIABLES FOR THE OFFSET TO SUBIFD
    UCHAR  SubIFDOffsettag[2]={
  0x69,0x87};
    UCHAR  SubIFDOffsetformat[2]={
  0x4,0x0};
    UCHAR  NcomponentSubIFDOffset[4]={
  0x1,0x0,0x0,0x0};
    UCHAR  SubIFDOffsetChar[4] = {
  0};


    //VARIABLES FOR THE EXPOSURE TIME
    UCHAR  ExposureTimetag[2]={
  0x9A,0x82};
    UCHAR  ExposureTimeformat[2]={
  0x5,0x0};
    UCHAR  NcomponentExposureTime[4]={
  0x1,0x0,0x0,0x0};
    UINT  ExposureTimeNum[1];
    UINT  ExposureTimeDen[1];

    UCHAR ExposureTimeoffchar[4];
    UCHAR ExposureTimeNumChar[4];
    UCHAR ExposureTimeDenChar[4];

    //VARIABLES FOR THE FNUMBER
    UCHAR  FNumbertag[2]={
  0x9D,0x82};
    UCHAR  FNumberformat[2]={
  0x5,0x0};
    UCHAR  NcomponentFNumber[4]={
  0x1,0x0,0x0,0x0};
    UINT  FNumberNum[1];
    UINT  FNumberDen[1];

    UCHAR FNumberoffchar[4];
    UCHAR FNumberNumChar[4];
    UCHAR FNumberDenChar[4];

    //VARIABLES FOR THE EXPOSURE PROGRAM OF THE CAMERA
    UCHAR  ExposureProgramtag[2]={
  0x22,0x88};
    UCHAR  ExposureProgramformat[2]={
  0x3,0x0};
    UCHAR  NcomponentExposureProgram[4]={
  0x1,0x0,0x0,0x0};
    UINT  ExposureProgram[1];
    UCHAR  ExposureProgramChar[4] = {
  0};

    //VARIABLES FOR THE ISO SPEED RATINGS OF THE CAMERA
    UCHAR  ISOSpeedRatingstag[2]={
  0x27,0x88};
    UCHAR  ISOSpeedRatingsformat[2]={
  0x3,0x0};
    UCHAR  NcomponentISOSpeedRatings[4]={
  0x2,0x0,0x0,0x0};
    unsigned short   ISOSpeedRatings[2];
    UCHAR  ISOSpeedRatingsChar[4] = {
  0};

    //VARIABLES FOR THE BRIGHTNESS OF THE IMAGE
    UCHAR  Brightnesstag[2]={
  0x03,0x92};
    UCHAR  Brightnessformat[2]={
  0xA,0x0};
    UCHAR  NcomponentBrightness[4]={
  0x1,0x0,0x0,0x0};
    int BrightnessNum[1];
    int BrightnessDen[1];

    UCHAR Brightnessoffchar[4];
    UCHAR BrightnessNumChar[4];
    UCHAR BrightnessDenChar[4];

    //VARIABLES FOR THE EXPOSURE Bias
    UCHAR  ExposureBiastag[2]={
  0x04,0x92};
    UCHAR  ExposureBiasformat[2]={
  0xA,0x0};
    UCHAR  NcomponentExposureBias[4]={
  0x1,0x0,0x0,0x0};
    int ExposureBiasNum[
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值