需要读取EXIF信息,自己阅读了一些资料,现在共享一下
需要注意的是,由于EXIF是一种可交换的文件格式,所以可以用在Intel系列和Motorola系列的CPU上(至于两者CPU的区别,大家可以到网上找找,这里不做说明)。在文件中有一个标志,如果是“MM”表示Motorola的CPU,否则为“II”表示Intel的CPU。
这个代码是使用C写的,读取文件用的API。本来我想写成一个VC使用的类的,但是自己还是太懒了。需要的自己去转换吧。
贴在这里主要就是这方面的资料国内太少了,希望本文能够帮助某部分人 :)
同样,下面贴出 .h 文件与 .c 文件,需要的人拷贝下来
// .h 文件
需要注意的是,由于EXIF是一种可交换的文件格式,所以可以用在Intel系列和Motorola系列的CPU上(至于两者CPU的区别,大家可以到网上找找,这里不做说明)。在文件中有一个标志,如果是“MM”表示Motorola的CPU,否则为“II”表示Intel的CPU。
这个代码是使用C写的,读取文件用的API。本来我想写成一个VC使用的类的,但是自己还是太懒了。需要的自己去转换吧。
贴在这里主要就是这方面的资料国内太少了,希望本文能够帮助某部分人 :)
同样,下面贴出 .h 文件与 .c 文件,需要的人拷贝下来
// .h 文件
/********************************************************************
Copyright@
版权所有@ 1998-2005hengai。保留所有权利。
********************************************************************/
/********************************************************************
文件说明: 能够读取 JPG 图像文件中的 EXIF 信息
文件名称: exif.h
版本号 : 1.0.0
作 者: hengai
修改纪录:
使用方法: 包含此头文件,然后调用函数
int EXIF_Read(LPCTSTR pszJpgFileName, EXIFINFO* pExifInfo)
即可获取 EXIF 信息。EXIF信息包含在参数 pExifInfo 中
在定义了 #define EXIF_OUTPUT_ERRMSG (默认下已经定义)后可以使用
LPCTSTR EXIF_GetErrorString();
获取出错信息
*********************************************************************
//
#ifndef
STATIC
#define
STATIC
static
#endif
#define
EXIF_OUTPUT_ERRMSG
//
定义是否输出出错信息
//
//
定义常量
#define
MAX_COMMENT
1000
//
最大的注释字符串长度
//
//
写入注释时,表明注释的类型,如 ASCII, UNICODE 等
typedef
enum
ECT
{
CT_ASCII
=
0
,
CT_UNICODE
,
CT_JIS
,
CT_UNDEFINE
}
COMMENT_TYPE
;
//
//
定义需要的结构体
#define
ET_NOT_CLOSE_FILE
0x00000001
//
最后不关闭打开的文件句柄
#define
ET_MALLOC_THUMBNAIL
0x00000002
//
拷贝缩略图的数据,调用者需要使用 free()
#define
ET_MALLOC_USERCOM
0x00000004
//
是否拷贝用户注释,调用者需要使用 free()
#define
ET_MALLOC_MAKERCOM
0x00000008
//
是否拷贝厂商注释,调用者需要使用 free()
//JPG
文件中的读入后的 EXIFF 信息保存到这个结构体中
typedef
struct
tag_ExifInfo
{
DWORD
dwExifType
;
//
取值为 ET_NOT_CLOSE_FILE|ET_MALLOC_THUMBNAIL, ....
DWORD
dwExifType2
;
char
Version
[
5
];
//EXIF
信息版本
char
CameraMake
[
32
];
//DC
制造商
char
CameraModel
[
40
];
//DC
型号
char
DateTime
[
20
];
//JPG
文件日期
char
DateTimeDigitized
[
20
];
//JPG
文件被其它软件修改日期
int
Height
,
Width
;
//
图像高度、宽度
int
Orientation
;
//
拍摄方向,例如相机向左手方向旋转后拍摄的
int
IsColor
;
//
int
Process
;
//
被处理
int
FlashUsed
;
//
是否使用闪光灯
float
FocalLength
;
//
焦距
float
ExposureTime
;
//
曝光时间(快门速度)
float
ApertureFNumber
;
//
光圈数
float
Distance
;
//
拍摄物体距离
float
CCDWidth
;
//CCD
大小
float
ExposureBias
;
//
曝光补偿
int
Whitebalance
;
//
白平衡
int
MeteringMode
;
//
测光模式
int
ExposureProgram
;
//
曝光
int
ISOequivalent
;
//ISO
int
CompressionLevel
;
//
压缩
float
FocalplaneXRes
;
//
焦平面X轴分辨率
float
FocalplaneYRes
;
//
焦平面Y轴分辨率
float
FocalplaneUnits
;
//
焦平面分辨率单位
float
Xresolution
;
//X
轴分辨率
float
Yresolution
;
//Y
轴分辨率
float
ResolutionUnit
;
//
分辨率单位
float
Brightness
;
//
亮度
char
Comments
[
MAX_COMMENT
];
//
注释
DWORD
UserCOMLength
;
//
用户注释长度。如果==0表示没有用户注释
char
*
UserCOM
;
//
用户注释
//if(dwExifType&ET_MALLOC_USERCOM == TRUE)
这个数值保存了用户注释数据,调用者需要使用 free()
//
否则为用户注释的偏移量(相对于文件起始0处)
DWORD
MakerCOMLength
;
//
厂商注释长度。如果==0表示没有厂商注释
char
*
MakerCOM
;
//
厂商注释
//if(dwExifType&ET_MALLOC_MAKERCOM == TRUE)
这个数值保存了厂商注释数据,调用者需要使用 free()
//
否则为厂商注释的偏移量(注意:是在当前SECTION中的偏移量,不是相对整个文件的)
UCHAR
*
ThumbnailPointer
;
//
缩略图数据。
//if(dwExifType&ET_MALLOC_THUMBNAIL == TRUE)
这个数值保存了缩略图的数据
//
否则为一个 DWORD(需要强制转换) 表示缩略图在JPG文件中的偏移值(相对于文件起始0处)
DWORD
ThumbnailSize
;
//
缩略图的大小(字节流 ThumbnailPointer 的长度)
//
如果<=0表示该 JPG 文件没有缩略图
HFILE
hJpgFileHandle
;
//
返回打开的 JPG 文件句柄。必须 dwExifType&ET_NOT_CLOSE_FILE == TRUE 才是有效句柄
//
用户需要使用 CloseHandle(hJpgFileHandle)来关闭这个句柄
BOOL
IsExif
;
//
是否存在 EXIF 信息
}
EXIFINFO
;
//
//
接口函数
int
EXIF_Read
(
LPCTSTR
pszJpgFileName
,
EXIFINFO
*
pExifInfo
);
LPCTSTR
EXIF_GetErrorString
();
int
EXIF_AddUserComments
(
LPCTSTR
pszJpgFileName
,
LPCTSTR
pszUserComments
,
DWORD
dwCommentLength
,
COMMENT_TYPE
nCommentType
);
// .c 文件
/********************************************************************
Copyright@
版权所有@ 1998-2005 HENGAI。保留所有权利。
********************************************************************/
/********************************************************************
文件说明:
文件名称: exif.c
版本号 : 1.0.0
作 者: hengai
修改纪录:
*********************************************************************/
#include
"exif.h"
//
//
读取 EXIF 过程中需要的结构体
typedef
struct
tag_Section_t
{
UCHAR
*
Data
;
int
Type
;
unsigned
Size
;
}
Section_t
;
//
#ifdef
EXIF_OUTPUT_ERRMSG
STATIC
TCHAR
m_szLastError
[
256
];
//
这里保存了出错的信息
#define
EXIF_ERR_OUT
(
str_err
)
strcpy
(
m_szLastError
,
str_err
);
LPCTSTR
EXIF_GetErrorString
()
{
return
(
LPCTSTR
)
m_szLastError
;
}
#else
#define
EXIF_ERR_OUT
LPCTSTR
EXIF_GetErrrorString
()
{
return
"Plese #define EXIT_ERR_OUT in exif.h"
;
}
#endif
STATIC
EXIFINFO
*
m_pExifInfo
=
0
;
//
STATIC
int
m_MotorolaOrder
=
0
;
//
STATIC
int
m_ExifImageWidth
=
0
;
//
//
/* Describes format descriptor */
static
const
int
m_BytesPerFormat
[] = {
0
,
1
,
1
,
2
,
4
,
8
,
1
,
1
,
2
,
4
,
8
,
4
,
8
};
#define
NUM_FORMATS
12
#define
FMT_BYTE
1
//Format Byte
#define
FMT_STRING
2
#define
FMT_USHORT
3
#define
FMT_ULONG
4
#define
FMT_URATIONAL
5
#define
FMT_SBYTE
6
#define
FMT_UNDEFINED
7
#define
FMT_SSHORT
8
#define
FMT_SLONG
9
#define
FMT_SRATIONAL
10
#define
FMT_SINGLE
11
#define
FMT_DOUBLE
12
//
#define
MAX_SECTIONS
20
//JPG
文件中能够允许的最多 SECTION 个数
#ifndef
M_SOI
#define
M_SOF0
0xC0
// Start Of Frame N
#define
M_SOF1
0xC1
// N indicates which compression process
#define
M_SOF2
0xC2
// Only SOF0-SOF2 are now in common use
#define
M_SOF3
0xC3
#define
M_SOF5
0xC5
// NB: codes C4 and CC are NOT SOF markers
#define
M_SOF6
0xC6
#define
M_SOF7
0xC7
#define
M_SOF9
0xC9
#define
M_SOF10
0xCA
#define
M_SOF11
0xCB
#define
M_SOF13
0xCD
#define
M_SOF14
0xCE
#define
M_SOF15
0xCF
#define
M_SOI
0xD8
// Start Of Image (beginning of datastream)
#define
M_EOI
0xD9
// End Of Image (end of datastream)
#define
M_SOS
0xDA
// Start Of Scan (begins compressed data)
#define
M_JFIF
0xE0
// Jfif marker
#define
M_EXIF
0xE1
// Exif marker
#define
M_COM
0xFE
// COMment
//
定义 APP 标识(SECTION)
#define
M_APP0
0xE0
#define
M_APP1
0xE1
#define
M_APP2
0xE2
#define
M_APP3
0xE3
#define
M_APP4
0xE4
#define
M_APP5
0xE5
#define
M_APP6
0xE6
//...
#endif
// Describes tag values
//
注意: 下面的定义是按照 Intel CPU 来定义的,也就是说所有的都是高位在后,
//
这样的定义可能与 EXIF 白皮书上的定义不一致。例如白皮书上把 TAG_MAKE 定义为 0F01
//
下面是主要信息
#define
TAG_MAKE
0x010F
//
相机DC 制造商
#define
TAG_MODEL
0x0110
//DC
型号
#define
TAG_ORIENTATION
0x0112
//
拍摄时方向,例如向左手旋转DC 90度拍摄照片
#define
TAG_XRESOLUTION
0x011A
//X
轴分辨率
#define
TAG_YRESOLUTION
0x011B
//Y
轴分辨率
#define
TAG_RESOLUTIONUNIT
0x0128
//
分辨率单位,例如 inch, cm
#define
TAG_DATATIME
0x0132
//
日期时间
#define
TAG_YBCR_POSITION
0x0213
//YCbCr
位置控制,例如 居中
#define
TAG_COPYRIGHT
0x8298
//
版权
#define
TAG_EXIF_OFFSET
0x8769
//EXIF
偏移,这时候相当于处理一个新的 EXIF 信息
//
#define
TAG_IMAGEWIDTH
0x0001
//
图像宽度
#define
TAG_IMAGEHEIGHT
0x0101
//
图像高度
//BOOKMARK
//
辅助信息
#define
TAG_EXPOSURETIME
0x829A
//
曝光时间,例如 1/30 秒
#define
TAG_FNUMBER
0x829D
//
光圈,例如 F2.8
#define
TAG_EXIF_VERSION
0x9000
//EXIF
信息版本
#define
TAG_DATETIME_ORIGINAL
0x9003
//
照片拍摄时间,例如 2005-10-13 11:09:35
#define
TAG_DATATIME_DIGITIZED
0x9004
//
相片被其它图像修改软件修改后的时间,例如 2005-10-13 11:36:35
#define
TAG_COMPONCONFIG
0x9101
//ComponentsConfiguration
色彩空间配置
#define
TAG_COMPRESS_BIT
0x9202
//
每像素压缩位数
#define
TAG_SHUTTERSPEED
0x9201
//
快门速度,例如 1/30 秒
#define
TAG_APERTURE
0x9202
//
光圈值,例如 F2.8
#define
TAG_BRIGHTNESS
0x9203
//
亮度
#define
TAG_EXPOSURE_BIAS
0x9204
//
曝光补偿,例如 EV0.0
#define
TAG_MAXAPERTURE
0x9205
//
最大光圈值,例如 F2.8
#define
TAG_SUBJECT_DISTANCE
0x9206
//
拍摄物距离,例如 3.11 米
#define
TAG_METERING_MODE
0x9207
//
测光模式,例如矩阵
#define
TAG_WHITEBALANCE
0x9208
//LightSource
白平衡
#define
TAG_FLASH
0x9209
//
是否使用闪光灯
#define
TAG_FOCALLENGTH
0x920A
//
焦距,例如 7.09mm
#define
TAG_USERCOMMENT
0x9286
//
用户注释
#define
TAG_MAKE_COMMENT
0x927C
//
厂商注释。这个版本不提供(2005-10-13)
#define
TAG_SUBSECTIME
0x9290
//SubSecTime
#define
TAG_SUBTIME_ORIGINAL
0x9291
//SubSecTimeOriginal
#define
TAG_SUBTIME_DIGITIZED
0x9292
//SubSecTimeDigitized
#define
TAG_FLASHPIXVERSION
0x00A0
//Flash Pix
版本
#define
TAG_COLORSPACE
0x01A0
//
色彩空间,例如 sRGB
#define
TAG_PIXEL_XDIMENSION
0x02A0
//
#define
TAG_PIXEL_YDIMENSION
0x03A0
//
#define
TAG_
//EXIFR98
//
缩略图
#define
TAG_INTEROP_OFFSET
0xa005
//
偏移
#define
TAG_FOCALPLANEXRES
0xA20E
//
焦平面X轴分辨率,例如 1024000/278
#define
TAG_FOCALPLANEYRES
0xA20F
//
焦平面X轴分辨率,例如 768000/209
#define
TAG_FOCALPLANEUNITS
0xA210
//
焦平面分辨率单位
#define
TAG_EXIF_IMAGEWIDTH
0xA002
//EXIF
图像宽度(就是这张 JPG 图像)
#define
TAG_EXIF_IMAGELENGTH
0xA003
//EXIF
图像高度
#define
TAG_EXPOSURE_PROGRAM
0x8822
//
#define
TAG_ISO_EQUIVALENT
0x8827
//