直接用 Image.Width/Height 获取像素宽高需确保图片已加载且未释放;常见错误是未判空或访问已释放对象;推荐用 Bitmap 构造加 try/catch 捕获格式不支持等异常;大图应优先解析元数据而非全量解码。

直接用 Image.Width 和 Image.Height 就能拿到像素宽高,但必须确保图片已成功加载且未被释放——这是新手踩坑最多的地方。
为什么 Width 和 Height 有时返回 0?
常见错误是:用 Image.FromFile() 加载后没检查是否为空,或在 using 块外访问已释放的对象。
-
Image.FromFile("xxx.jpg")在文件被占用、路径错、格式不支持时会抛异常,不抛异常也可能返回null,但新手常忽略判空 - 写成
using (var img = Image.FromFile(...)) { ... img.Width ... }是安全的;但如果把img存到字段里后续再读Width,运行时大概率报ObjectDisposedException - GDI+ 不支持 WebP、AVIF 等新格式,强行加载会失败,
Width拿不到
更稳妥的获取方式:用 Bitmap + try/catch
Bitmap 是 Image 的子类,构造时会强制解码,失败立刻暴露问题,比懒加载的 Image 更可控。
try
{
using (var bmp = new Bitmap("photo.png"))
{
int w = bmp.Width;
int h = bmp.Height;
Console.WriteLine($"{w}x{h}");
}
}
catch (ArgumentException)
{
// 路径无效或不是图像文件
}
catch (OutOfMemoryException)
{
// 格式不支持(如 WebP)或文件损坏
}
-
OutOfMemoryException是 GDI+ 对“不支持格式”的统一报错,别被名字误导 - 如果必须支持 WebP,改用
ImageSharp库的Image.Load(...),它返回ImageInfo.Width/Height - 大图(比如 100MB TIFF)用
Bitmap构造会瞬间占满内存,此时应改用元数据解析(见下一条)
只读宽高不加载全图:用 ImageCodecInfo 或第三方元数据库
打开一张 8000×6000 的 PNG,Bitmap 会解码成约 192MB 的位图内存;其实宽高信息早藏在文件头里,没必要全解。
- .NET 6+ 可用
Image.Decoder.GetDecoderInfo()配合流读取前几百字节,但 API 较底层,易出错 - 推荐轻量方案:
System.Drawing.Common不行,就换MetadataExtractorNuGet 包:var directories = ImageMetadataReader.ReadMetadata(fileStream);
然后找JpegDirectory或PngDirectory里的TagImageWidth/TagImageHeight - 注意:某些相机生成的 JPEG 有旋转标记(
Orientation),此时Width/Height是原始尺寸,人眼看到的“实际宽高”可能要交换
真正麻烦的从来不是读两个数字,而是得判断该走快速元数据路径,还是必须解码——这取决于你的场景:做缩略图就得解码,做文件列表就该跳过解码。另外,.NET Core 3.1+ 在 Linux 上跑 System.Drawing 需装 libgdiplus,否则连 Width 都拿不到,这个依赖容易被忽略。


















