用C#读取数码相片的EXIF信息(一)

来源:互联网 发布:赵寅成 两天一夜 知乎 编辑:程序博客网 时间:2024/05/16 19:23
 

现在的数码相机拍摄出来的照片表面上看都是很普通的JPEG的图片,但通常还包含着诸如相片拍摄时使用的相机生产商、型号、光圈值、快门速度等各类附加信息,这就是所谓的Exif信息。Exif是一种图像文件格式,只是文件的后缀名还是沿用大家熟悉的jpg而已。掌握Exif信息对学习提高摄影技术很有帮助。

C#.NET作为一种现代的全能开发语言,对EXIF也有着较好的支持。在.NET中,我们可以用PropertyItem对象来获取EXIF。

取得PropertyItem很简单。

Image img = Image.FromFile("支持Exif的图片文件");           
PropertyItem[] pt = img.PropertyItems;

这样就可以了,Exif信息都已载入到PropertyItem数组中了。

其中PropertyItem的ID,Type,Value属性是最重要的。

ID可以唯一表明当前PropertyItem的含义。比如,0x010F代表相机制造商,0x8827代表ISO速度,0x829D代表相机F值。这在MSDN中有非常详尽的介绍。我们首先需要花一定的精力将这些数字翻译成人类可理解的自然语言。这个实现起来很简单但是很无聊,做成HashTable或自己写一堆case都可以,看个人喜欢吧。

Value永远都是字节数组,但具体内容的取值方法随Type不同而不同。

Type是个整数,表示的类型在MSDN中是这么描述的:
 
1 指定 Value 为字节数组。
 
2 指定 Value 为空终止 ASCII 字符串。如果将类型数据成员设置为 ASCII 类型,则应该将 Len 属性设置为包括空终止的字符串长度。例如,字符串“Hello”的长度为 6。
 
3 指定 Value 为无符号的短(16 位)整型数组。
 
4 指定 Value 为无符号的长(32 位)整型数组。
 
5 指定 Value 数据成员为无符号的长整型对数组。每一对都表示一个分数;第一个整数是分子,第二个整数是分母。
 
6 指定 Value 为可以包含任何数据类型的值的字节数组。
 
7 指定 Value 为有符号的长(32 位)整型数组。
 
10 指定 Value 为有符号的长整型对数组。每一对都表示一个分数;第一个整数是分子,第二个整数是分母。

所以取Exif的算法重点在于如何根据Type值将Value字节数组变成人类可以理解的值。

获取每一条Exif信息算法的框架大概是这样的:
foreach (PropertyItem p in pt)
{
 switch(p.Type)
 { 
  case 1:
   CurrentExifDetail = GetValueOfType1(byte[] b);
   break;
  case 2:
   CurrentExifDetail = GetValueOfType2(byte[] b);
   break;
  ...
 }

 CurrentExifInfo = 翻译ID到人类可读文字(p.ID.ToString()) + ":" + CurrentExifDetail;
}


举个实际例子来看看。比如,当我们扫描PropertyItem到D == 0x0110,发现其Type = 2,说明Value里的值就是C格式的普通字符数组,一个个取出来就是人类可以阅读的字符串了。

public string GetValueOfType2(byte[] b)
{
    return System.Text.Encoding.ASCII.GetString(b);
}

在接下来的文章中,我们将仔细讨论各种Type应该如何取值。

原创粉丝点击