用C#读取图片的EXIF信息的方法
用C#读取图片的EXIF信息的方法
引言:
EXIF,是英文Exchangeable Image File(可交换图像文件)的缩写,最初由日本电子工业发展协会(JEIDA --Japan Electronic Industry Development Association) 制订,目前的版本是修改发表于1998年6月的2.1版。国际标准化组织(ISO)正在制订的相机文件设计标准(DCF -- Design role for Camera File system)就是以EXIF2.1格式为基础而设定的。记住,EXIF是一种图像文件格式,只是文件的后缀名还是沿用大家熟悉的jpg而已。实际上,EXIF信息就是由数码相机在拍摄过程中采集一系列的信息,然后把信息放置在我们熟知的jpg文件的头部,也就是说EXIF信息是镶嵌在JPEG图像文件格式内的一组拍摄参数,主要包括摄影时的光圈、快门、ISO、日期时间等各种与当时摄影条件相关的讯息,相机品牌型号,色彩编码,拍摄时录制的声音以及全球定位系统(GPS)等信息。简单的说,它就好像是傻瓜相机的日期打印功能一样,只不过EXIF信息所记录的资讯更为详尽和完备。不过,具有EXIF信息的JPEG图像文件要比普通的JPEG文件略大一点。就目前市场而言,新一代的数码相机都具有附加EXIF信息功能,大多数的数码相机厂商也都会随数码相机发售时附赠能够读取EXIF信息的软件,例如 Nikon 系列的数码相机就附赠 NikonView 软件,Agfa系列的相机则附赠 Photowize V1.8版,而富士相机附送的EXIF viewer软件更是这方面的领军人物(目前已在很多网站提供免费下载。还有一部分的数码相机会自动将EXIF信息转存成文档文件,例如:NIKON CoolPix 990和SONY FD系列。除了硬件厂商随数码相机附带的EXIF信息查看软件,很多专业的图像软件厂商在这方面也不甘示弱,相继推出自己公司看图软件的最新版来支持这种近乎完美的JPEG-EXIF图像信息附加技术,如最近刚推出的ACDSee 4.0版本,就对现在流行的各种数码相机有相当好的支持,在EXIF图像信息附加方面较之其3.0版本也有很大的进步。不管是硬件厂商的配套软件还是专业名门的看图工具,所有这些软件都是为了方便数码摄影者能更方便地保存查看摄影图像的重要信息。我们将这些读取EXIF信息的软件归纳后分为四类:专业EXIF信息查看工具(以富士的EXIF viewer为例) 、具有查看EXIF信息的强大通用看图工具(以ACDSee为例)、支持EXIF信息查看的操作系统(微软的Windows XP)以及可以修改EXIF信息的另类工具(EXIF Editer),而我们这里要讲的是通过C#在WEB上读取一个图片的EXIF信息。
二、相关类(GetEXIFMetaData):
因为代码比较长,有五百多行,我只能将关键代码的片段拿出来讲讲,这个类中构造了两个结构MetadataDetail 和 Metadata ,前者是为了存储EXIF中某元素信息的三种格式,起到中间转化的作用,一个是十六进制的索引信息,一个是没用处理过的信息代码,一个是显示信息。后面的那个结构就是存储一张图片所有EXIF信息元素的。 有两个方法LookupEXIFValue 和 GetEXIFMetaData ,前一个方法是处理特殊元素的对应显示的,后者从图片中读取相关信息然后填充到MetaData结构中。
using System.Drawing;
using System.Drawing.Imaging;
using System.Collections;
using System.ComponentModel;
namespace Test.Image
{
/// <summary>
/// 功能:获得图片EXIF信息
/// 作者:Rexsp
/// 创建日期:2004-03-20
/// 作者MSN:yubo@x263.net
/// </summary>
public class EXIFMetaData
{
构造函数
数据转换结构
#region EXIF元素结构
/// <summary>
/// 结构:存储EXIF元素信息
/// </summary>
public struct Metadata
{
public MetadataDetail EquipmentMake;
public MetadataDetail CameraModel;
public MetadataDetail ExposureTime;//曝光时间
public MetadataDetail Fstop;
public MetadataDetail DatePictureTaken;
public MetadataDetail ShutterSpeed;// 快门速度
public MetadataDetail MeteringMode;//曝光模式
public MetadataDetail Flash;//闪光灯
public MetadataDetail XResolution;
public MetadataDetail YResolution;
public MetadataDetail ImageWidth;//照片宽度
public MetadataDetail ImageHeight;//照片高度
public MetadataDetail FNumber;// added f值,光圈数
public MetadataDetail ExposureProg;// added 曝光程序
public MetadataDetail SpectralSense;// added
public MetadataDetail ISOSpeed;// added ISO感光度
public MetadataDetail OECF;// added
public MetadataDetail Ver;// added EXIF版本
public MetadataDetail CompConfig;// added 色彩设置
public MetadataDetail CompBPP;// added 压缩比率
public MetadataDetail Aperture;// added 光圈值
public MetadataDetail Brightness;// added 亮度值Ev
public MetadataDetail ExposureBias;// added 曝光补偿
public MetadataDetail MaxAperture;// added 最大光圈值
public MetadataDetail SubjectDist;// added主体距离
public MetadataDetail LightSource;// added 白平衡
public MetadataDetail FocalLength;// added 焦距
public MetadataDetail FPXVer;// added FlashPix版本
public MetadataDetail ColorSpace;// added 色彩空间
public MetadataDetail Interop;// added
public MetadataDetail FlashEnergy;// added
public MetadataDetail SpatialFR;// added
public MetadataDetail FocalXRes;// added
public MetadataDetail FocalYRes;// added
public MetadataDetail FocalResUnit;// added
public MetadataDetail ExposureIndex;// added 曝光指数
public MetadataDetail SensingMethod;// added 感应方式
public MetadataDetail SceneType;// added
public MetadataDetail CfaPattern;// added
}
#endregion
#region 查找EXIF元素值
public string LookupEXIFValue(string Description, string Value)
{
string DescriptionValue = null;
switch(Description)
{
case "MeteringMode":
MeteringMode
break;
case "ResolutionUnit":
ResolutionUnit
break;
case "Flash":
Flash
break;
case "ExposureProg":
ExposureProg
break;
case "CompConfig":
CompConfig
break;
case "Aperture":
Aperture
break;
case "LightSource":
LightSource
break;
}
return DescriptionValue;
}
#endregion
#region 取得图片的EXIF信息
public Metadata GetEXIFMetaData(string PhotoName)
{
// 创建一个图片的实例
System.Drawing.Image MyImage = System.Drawing.Image.FromFile(PhotoName);
// 创建一个整型数组来存储图像中属性数组的ID
int[] MyPropertyIdList = MyImage.PropertyIdList;
//创建一个封闭图像属性数组的实例
PropertyItem[] MyPropertyItemList = new PropertyItem[MyPropertyIdList.Length];
//创建一个图像EXIT信息的实例结构对象,并且赋初值
创建一个图像EXIT信息的实例结构对象,并且赋初值
// ASCII编码
System.Text.ASCIIEncoding Value = new System.Text.ASCIIEncoding();
int index = 0;
int MyPropertyIdListCount=MyPropertyIdList.Length;
if(MyPropertyIdListCount!=0)
{
foreach (int MyPropertyId in MyPropertyIdList)
{
string hexVal = "";
MyPropertyItemList[index] = MyImage.GetPropertyItem(MyPropertyId);
初始化各属性值
index++;
}
}
MyMetadata.XResolution.DisplayValue = MyImage.HorizontalResolution.ToString();
MyMetadata.YResolution.DisplayValue = MyImage.VerticalResolution.ToString();
MyMetadata.ImageHeight.DisplayValue = MyImage.Height.ToString();
MyMetadata.ImageWidth.DisplayValue = MyImage.Width.ToString();
MyImage.Dispose();
return MyMetadata;
}
#endregion
}
}
然后就是个调用的问题,有了这个类,我如何读取图片的EXIF信息呢?代码如下:
string filePath=Server.MapPath("Test.jpg");//这里可以动态传递图片路径的
EXIFMetaData.Metadata m = em.GetEXIFMetaData(filePath);//这里就是调用,传图片绝对路径
string exif = m.Ver.DisplayValue;
string camera = m.CameraModel.DisplayValue;
string model = m.CameraModel.DisplayValue;
string aperture = m.Aperture.DisplayValue;
string shutter = m.ShutterSpeed.DisplayValue;
string sensitive = m.ExposureIndex.DisplayValue;
有什么不明白的,欢迎提出来,此代码经过测试,功能正常。