用C#讀取圖片的EXIF信息的方法
發(fā)表時(shí)間:2024-02-08 來(lái)源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]引言:EXIF,是英文Exchangeable Image File(可交換圖像文件)的縮寫(xiě),最初由日本電子工業(yè)發(fā)展協(xié)會(huì)(JEIDA --Japan Electronic Industry Development Association) 制訂,目前的版本是修改發(fā)表于1998年6月的2.1版。國(guó)際...
引言:
EXIF,是英文Exchangeable Image File(可交換圖像文件)的縮寫(xiě),最初由日本電子工業(yè)發(fā)展協(xié)會(huì)(JEIDA --Japan Electronic Industry Development Association) 制訂,目前的版本是修改發(fā)表于1998年6月的2.1版。國(guó)際標(biāo)準(zhǔn)化組織(ISO)正在制訂的相機(jī)文件設(shè)計(jì)標(biāo)準(zhǔn)(DCF -- Design role for Camera File system)就是以EXIF2.1格式為基礎(chǔ)而設(shè)定的。記住,EXIF是一種圖像文件格式,只是文件的后綴名還是沿用大家熟悉的jpg而已。實(shí)際上,EXIF信息就是由數(shù)碼相機(jī)在拍攝過(guò)程中采集一系列的信息,然后把信息放置在我們熟知的jpg文件的頭部,也就是說(shuō)EXIF信息是鑲嵌在JPEG圖像文件格式內(nèi)的一組拍攝參數(shù),主要包括攝影時(shí)的光圈、快門(mén)、ISO、日期時(shí)間等各種與當(dāng)時(shí)攝影條件相關(guān)的訊息,相機(jī)品牌型號(hào),色彩編碼,拍攝時(shí)錄制的聲音以及全球定位系統(tǒng)(GPS)等信息。簡(jiǎn)單的說(shuō),它就好像是傻瓜相機(jī)的日期打印功能一樣,只不過(guò)EXIF信息所記錄的資訊更為詳盡和完備。不過(guò),具有EXIF信息的JPEG圖像文件要比普通的JPEG文件略大一點(diǎn)。就目前市場(chǎng)而言,新一代的數(shù)碼相機(jī)都具有附加EXIF信息功能,大多數(shù)的數(shù)碼相機(jī)廠商也都會(huì)隨數(shù)碼相機(jī)發(fā)售時(shí)附贈(zèng)能夠讀取EXIF信息的軟件,例如 Nikon 系列的數(shù)碼相機(jī)就附贈(zèng) NikonView 軟件,Agfa系列的相機(jī)則附贈(zèng) Photowize V1.8版,而富士相機(jī)附送的EXIF viewer軟件更是這方面的領(lǐng)軍人物(目前已在很多網(wǎng)站提供免費(fèi)下載。還有一部分的數(shù)碼相機(jī)會(huì)自動(dòng)將EXIF信息轉(zhuǎn)存成文檔文件,例如:NIKON CoolPix 990和SONY FD系列。除了硬件廠商隨數(shù)碼相機(jī)附帶的EXIF信息查看軟件,很多專業(yè)的圖像軟件廠商在這方面也不甘示弱,相繼推出自己公司看圖軟件的最新版來(lái)支持這種近乎完美的JPEG-EXIF圖像信息附加技術(shù),如最近剛推出的ACDSee 4.0版本,就對(duì)現(xiàn)在流行的各種數(shù)碼相機(jī)有相當(dāng)好的支持,在EXIF圖像信息附加方面較之其3.0版本也有很大的進(jìn)步。不管是硬件廠商的配套軟件還是專業(yè)名門(mén)的看圖工具,所有這些軟件都是為了方便數(shù)碼攝影者能更方便地保存查看攝影圖像的重要信息。我們將這些讀取EXIF信息的軟件歸納后分為四類:專業(yè)EXIF信息查看工具(以富士的EXIF viewer為例) 、具有查看EXIF信息的強(qiáng)大通用看圖工具(以ACDSee為例)、支持EXIF信息查看的操作系統(tǒng)(微軟的Windows XP)以及可以修改EXIF信息的另類工具(EXIF Editer),而我們這里要講的是通過(guò)C#在WEB上讀取一個(gè)圖片的EXIF信息。
二、相關(guān)類(GetEXIFMetaData):
因?yàn)榇a比較長(zhǎng),有五百多行,我只能將關(guān)鍵代碼的片段拿出來(lái)講講,需要源碼的請(qǐng)發(fā)郵件到 yubo@x263.net 索取,或者直接加到MSN上在MSN提供你的郵箱。
這個(gè)類中構(gòu)造了兩個(gè)結(jié)構(gòu)MetadataDetail 和 Metadata ,前者是為了存儲(chǔ)EXIF中某元素信息的三種格式,起到中間轉(zhuǎn)化的作用,一個(gè)是十六進(jìn)制的索引信息,一個(gè)是沒(méi)用處理過(guò)的信息代碼,一個(gè)是顯示信息。后面的那個(gè)結(jié)構(gòu)就是存儲(chǔ)一張圖片所有EXIF信息元素的!∮袃蓚(gè)方法LookupEXIFValue 和 GetEXIFMetaData ,前一個(gè)方法是處理特殊元素的對(duì)應(yīng)顯示的,后者從圖片中讀取相關(guān)信息然后填充到MetaData結(jié)構(gòu)中。
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Collections;
using System.ComponentModel;
namespace Test.Com
{
/// <summary>
/// 功能:獲得圖片EXIF信息
/// 作者:Rexsp
/// 創(chuàng)建日期:2004-03-20
/// </summary>
public class EXIFMetaData
{
#region 構(gòu)造函數(shù)
/// <summary>
/// 構(gòu)造函數(shù)
/// </summary>
public EXIFMetaData()
{
}
#endregion
#region 數(shù)據(jù)轉(zhuǎn)換結(jié)構(gòu)
/// <summary>
/// 轉(zhuǎn)換數(shù)據(jù)結(jié)構(gòu)
/// </summary>
public struct MetadataDetail
{
public string Hex;//十六進(jìn)制字符串
public string RawValueAsString;//原始值串
public string DisplayValue;//顯示值串
}
#endregion
#region EXIF元素結(jié)構(gòu)
/// <summary>
/// 結(jié)構(gòu):存儲(chǔ)EXIF元素信息
/// </summary>
public struct Metadata
{
public MetadataDetail EquipmentMake;
public MetadataDetail CameraModel;
public MetadataDetail ExposureTime;//曝光時(shí)間
public MetadataDetail Fstop;
public MetadataDetail DatePictureTaken;
public MetadataDetail ShutterSpeed;// 快門(mén)速度
public MetadataDetail MeteringMode;//曝光模式
public MetadataDetail Flash;//閃光燈
public MetadataDetail XResolution;
public MetadataDetail YResolution;
public MetadataDetail ImageWidth;//照片寬度
public MetadataDetail ImageHeight;//照片高度
public MetadataDetail FNumber;// f值,光圈數(shù)
public MetadataDetail ExposureProg;// 曝光程序
public MetadataDetail SpectralSense;//
public MetadataDetail ISOSpeed;// ISO感光度
public MetadataDetail OECF;//
public MetadataDetail Ver;// EXIF版本
public MetadataDetail CompConfig;// 色彩設(shè)置
public MetadataDetail CompBPP;// 壓縮比率
public MetadataDetail Aperture;// 光圈值
public MetadataDetail Brightness;// 亮度值Ev
public MetadataDetail ExposureBias;// 曝光補(bǔ)償
public MetadataDetail MaxAperture;// 最大光圈值
public MetadataDetail SubjectDist;// 主體距離
public MetadataDetail LightSource;// 白平衡
public MetadataDetail FocalLength;// 焦距
public MetadataDetail FPXVer;// FlashPix版本
public MetadataDetail ColorSpace;// 色彩空間
public MetadataDetail Interop;//
public MetadataDetail FlashEnergy;//
public MetadataDetail SpatialFR;//
public MetadataDetail FocalXRes;//
public MetadataDetail FocalYRes;//
public MetadataDetail FocalResUnit;//
public MetadataDetail ExposureIndex;// 曝光指數(shù)
public MetadataDetail SensingMethod;// 感應(yīng)方式
public MetadataDetail SceneType;//
public MetadataDetail CfaPattern;//
}
#endregion
#region 查找EXIF元素值
public string LookupEXIFValue(string Description, string Value)
{
string DescriptionValue = null;
switch(Description)
{
case "MeteringMode":
#region MeteringMode
{
switch(Value)
{
case "0":
DescriptionValue = "Unknown";break;
case "1":
DescriptionValue = "Average";break;
case "2":
DescriptionValue = "Center Weighted Average";break;
case "3":
DescriptionValue = "Spot";break;
case "4":
DescriptionValue = "Multi-spot";break;
case "5":
DescriptionValue = "Multi-segment";break;
case "6":
DescriptionValue = "Partial";break;
case "255":
DescriptionValue = "Other";break;
}
}
#endregion
break;
case "ResolutionUnit":
#region ResolutionUnit
{
switch(Value)
{
case "1":
DescriptionValue = "No Units";break;
case "2":
DescriptionValue = "Inch";break;
case "3":
DescriptionValue = "Centimeter";break;
}
}
#endregion
break;
//省略N行相似代碼
}
return DescriptionValue;
}
#endregion
#region 取得圖片的EXIF信息
public Metadata GetEXIFMetaData(string PhotoName)
{
// 創(chuàng)建一個(gè)圖片的實(shí)例
System.Drawing.Image MyImage = System.Drawing.Image.FromFile(PhotoName);
// 創(chuàng)建一個(gè)整型數(shù)組來(lái)存儲(chǔ)圖像中屬性數(shù)組的ID
int[] MyPropertyIdList = MyImage.PropertyIdList;
//創(chuàng)建一個(gè)封閉圖像屬性數(shù)組的實(shí)例
PropertyItem[] MyPropertyItemList = new PropertyItem[MyPropertyIdList.Length];
//創(chuàng)建一個(gè)圖像EXIT信息的實(shí)例結(jié)構(gòu)對(duì)象,并且賦初值
#region 創(chuàng)建一個(gè)圖像EXIT信息的實(shí)例結(jié)構(gòu)對(duì)象,并且賦初值
Metadata MyMetadata = new Metadata();
MyMetadata.EquipmentMake.Hex = "10f";
MyMetadata.CameraModel.Hex = "110";
MyMetadata.DatePictureTaken.Hex = "9003";
MyMetadata.ExposureTime.Hex = "829a";
MyMetadata.Fstop.Hex = "829d";
MyMetadata.ShutterSpeed.Hex = "9201";
MyMetadata.MeteringMode.Hex = "9207";
MyMetadata.Flash.Hex = "9209";
MyMetadata.FNumber.Hex = "829d"; //
MyMetadata.ExposureProg.Hex = ""; //
MyMetadata.SpectralSense.Hex = "8824"; //
MyMetadata.ISOSpeed.Hex = "8827"; //
MyMetadata.OECF.Hex = "8828"; //
MyMetadata.Ver.Hex = "9000"; //
MyMetadata.CompConfig.Hex = "9101"; //
MyMetadata.CompBPP.Hex = "9102"; //
MyMetadata.Aperture.Hex = "9202"; //
MyMetadata.Brightness.Hex = "9203"; //
MyMetadata.ExposureBias.Hex = "9204"; //
MyMetadata.MaxAperture.Hex = "9205"; //
MyMetadata.SubjectDist.Hex = "9206"; //
MyMetadata.LightSource.Hex = "9208"; //
MyMetadata.FocalLength.Hex = "920a"; //
MyMetadata.FPXVer.Hex = "a000"; //
MyMetadata.ColorSpace.Hex = "a001"; //
MyMetadata.FocalXRes.Hex = "a20e"; //
MyMetadata.FocalYRes.Hex = "a20f"; //
MyMetadata.FocalResUnit.Hex = "a210"; //
MyMetadata.ExposureIndex.Hex = "a215"; //
MyMetadata.SensingMethod.Hex = "a217"; //
MyMetadata.SceneType.Hex = "a301";
MyMetadata.CfaPattern.Hex = "a302";
#endregion
// 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);
#region 初始化各屬性值
string myPropertyIdString=MyImage.GetPropertyItem(MyPropertyId).Id.ToString("x");
switch(myPropertyIdString)
{
case "10f":
{
MyMetadata.EquipmentMake.RawValueAsString =BitConverter.ToString(MyImage.GetPropertyItem (MyPropertyId).Value);
MyMetadata.EquipmentMake.DisplayValue = Value.GetString(MyPropertyItemList[index].Value);
break;
}
case "110":
{
MyMetadata.CameraModel.RawValueAsString =BitConverter.ToString(MyImage.GetPropertyItem(MyPropertyId).Value);
MyMetadata.CameraModel.DisplayValue =Value.GetString(MyPropertyItemList[index].Value);
break;
}
case "9003":
{
MyMetadata.DatePictureTaken.RawValueAsString =BitConverter.ToString(MyImage.GetPropertyItem(MyPropertyId).Value);
MyMetadata.DatePictureTaken.DisplayValue =Value.GetString(MyPropertyItemList[index].Value);
break;
}
//省略N行相似代碼
}
#endregion
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
}
}
然后就是個(gè)調(diào)用的問(wèn)題,有了這個(gè)類,我如何讀取圖片的EXIF信息呢?代碼如下:
EXIFMetaData em = new EXIFMetaData();
string filePath=Server.MapPath("Test.jpg");//這里可以動(dòng)態(tài)傳遞圖片路徑的
EXIFMetaData.Metadata m = em.GetEXIFMetaData(filePath);//這里就是調(diào)用,傳圖片絕對(duì)路徑
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;
有什么不明白的,歡迎提出來(lái),此代碼經(jīng)過(guò)測(cè)試,功能正常。