在C#开发中,读取图片的EXIF信息是获取照片元数据的常用需求,EXIF信息包含了照片的拍摄参数、设备信息、时间记录等内容,这些信息被嵌入在图片文件的特定数据段中。通过C#自带的图像处理类,我们可以快速提取这些有用的元数据,无需依赖第三方库即可完成基础的信息读取。

EXIF信息的基本概念
EXIF是可交换图像文件格式的缩写,是专门为数码相机照片设定的标准,用来记录数码照片的属性信息和拍摄数据。常见的EXIF信息包括拍摄日期、相机品牌型号、光圈、快门速度、ISO感光度、图像分辨率、GPS定位信息等。在C#中,我们可以通过System.Drawing命名空间下的Image类来访问这些信息。
核心类与属性说明
读取EXIF信息主要依赖Image类和PropertyItem类:
Image类:表示图像对象,通过FromFile方法可以加载本地图片文件,其PropertyItems属性可以获取图片的所有属性项集合。PropertyItem类:表示图像的一个属性项,包含了属性ID、类型、长度和数据内容,其中Id属性对应EXIF属性的标识,Value属性存储属性的具体值。
常见EXIF属性ID对照
不同的EXIF信息对应不同的属性ID,以下是常用的属性ID及含义:
| 属性ID | 含义 | 数据类型 |
|---|---|---|
| 0x0132 | 拍摄日期时间 | 字符串 |
| 0x010F | 相机制造商 | 字符串 |
| 0x0110 | 相机型号 | 字符串 |
| 0x829A | 曝光时间 | 有理数 |
| 0x829D | 光圈值 | 有理数 |
| 0x8827 | ISO感光度 | 短整型 |
| 0x0103 | 图像宽度 | 长整型 |
| 0x0102 | 图像高度 | 长整型 |
完整实现代码示例
以下是读取图片EXIF信息的完整C#代码,包含加载图片、遍历属性、解析常见属性值的功能:
using System;
using System.Drawing;
using System.Text;
namespace ExifReaderDemo
{
class Program
{
static void Main(string[] args)
{
// 图片路径,替换为实际图片路径
string imagePath = @"C:testphoto.jpg";
try
{
// 加载图片文件
using (Image img = Image.FromFile(imagePath))
{
Console.WriteLine("图片EXIF信息列表:");
// 遍历所有属性项
foreach (PropertyItem propItem in img.PropertyItems)
{
string propValue = ParsePropertyValue(propItem);
string propName = GetPropertyName(propItem.Id);
Console.WriteLine($"属性ID: 0x{propItem.Id:X4}, 名称: {propName}, 值: {propValue}");
}
}
}
catch (Exception ex)
{
Console.WriteLine($"读取失败:{ex.Message}");
}
}
/// <summary>
/// 根据属性ID获取属性名称
/// </summary>
static string GetPropertyName(int id)
{
switch (id)
{
case 0x0132: return "拍摄日期时间";
case 0x010F: return "相机制造商";
case 0x0110: return "相机型号";
case 0x829A: return "曝光时间";
case 0x829D: return "光圈值";
case 0x8827: return "ISO感光度";
case 0x0103: return "图像宽度";
case 0x0102: return "图像高度";
default: return "未知属性";
}
}
/// <summary>
/// 解析属性值
/// </summary>
static string ParsePropertyValue(PropertyItem propItem)
{
switch (propItem.Type)
{
// 字符串类型
case 2:
return Encoding.UTF8.GetString(propItem.Value).TrimEnd(' ');
// 短整型数组
case 3:
return BitConverter.ToUInt16(propItem.Value, 0).ToString();
// 长整型数组
case 4:
return BitConverter.ToUInt32(propItem.Value, 0).ToString();
// 有理数类型,由两个长整型组成,分子/分母
case 5:
uint numerator = BitConverter.ToUInt32(propItem.Value, 0);
uint denominator = BitConverter.ToUInt32(propItem.Value, 4);
if (denominator == 0) return "0";
return ((double)numerator / denominator).ToString("F3");
// 字节数组
case 1:
return BitConverter.ToString(propItem.Value);
default:
return BitConverter.ToString(propItem.Value);
}
}
}
}
注意事项
- 需要引用
System.Drawing程序集,在.NET Core或.NET 5+项目中,需要安装System.Drawing.CommonNuGet包。 - 不是所有图片都包含完整的EXIF信息,部分图片可能没有某些属性项,遍历时不会报错,但对应属性不会显示。
- 解析属性值时需要根据
PropertyItem.Type字段判断数据类型,不同类型的数据解析方式不同,错误解析会导致数据异常。 - 读取完成后需要及时释放
Image对象,避免文件被占用,使用using语句可以自动完成释放操作。
扩展说明
如果需要读取更复杂的EXIF信息,比如GPS定位信息、缩略图数据等,可以参考EXIF官方标准文档,对应更多的属性ID和解析规则。如果需要处理大量图片的EXIF信息,建议将解析逻辑封装为独立的工具类,提高代码的复用性。对于没有EXIF信息的图片,也可以尝试读取图片的基础属性,比如尺寸、格式等,这些属性可以直接通过Image类的Width和Height属性获取。
C#EXIF信息照片元数据Image类PropertyItem修改时间:2026-06-18 12:00:19