如何在不加载图像的情况下可靠地获取.NET中的图像尺寸?

Sim*_*ver 24 .net image

我知道如何获得图像的大小(x,y)

Image.FromFile("cat.jpg").Size
Run Code Online (Sandbox Code Playgroud)

但这需要从内存加载图像.

当我在Windows资源管理器中查看图像时,它显示了我的大小.

  • 我如何访问该大小?
  • 所有图像都可靠吗?Windows资源管理器是否需要首先"看到"图像以获得可用的大小.在将其加载到Internet Explorer之前,我不想上传到服务器并且没有可用的元数据.

编辑:我将主题从"尺寸"更改为"尺寸",以阐明我想要的尺寸.

Qry*_*taL 36

您可以使用Image.FromStream(Stream, bool, bool)"false"第二和第三个参数来避免将文件加载到内存中.

  • 这怎么不读取整个文件??? (4认同)
  • 例如。`Image.FromStream(File.OpenRead(file.PhysicalPath), false, false)` (3认同)

ama*_*int 11

如果你想在不加载图像的情况下获得图像尺寸(宽度和高度),你需要自己阅读jpeg文件的某些部分,如下所示.

这是一个开箱即用的方法:)

public static Size GetJpegImageSize(string filename) {
    FileStream stream=null;
    BinaryReader rdr=null;
    try {
        stream=File.OpenRead(filename);
        rdr=new BinaryReader(stream);
        // keep reading packets until we find one that contains Size info
        for(; ; ) {
            byte code=rdr.ReadByte();
            if(code!=0xFF) throw new ApplicationException(
                    "Unexpected value in file "+filename);
            code=rdr.ReadByte();
            switch(code) {
                // filler byte
                case 0xFF:
                    stream.Position--;
                    break;
                // packets without data
                case 0xD0: case 0xD1: case 0xD2: case 0xD3: case 0xD4: 
                case 0xD5: case 0xD6: case 0xD7: case 0xD8: case 0xD9:
                    break;
                // packets with size information
                case 0xC0: case 0xC1: case 0xC2: case 0xC3:
                case 0xC4: case 0xC5: case 0xC6: case 0xC7:
                case 0xC8: case 0xC9: case 0xCA: case 0xCB:
                case 0xCC: case 0xCD: case 0xCE: case 0xCF:
                    ReadBEUshort(rdr);
                    rdr.ReadByte();
                    ushort h=ReadBEUshort(rdr);
                    ushort w=ReadBEUshort(rdr);
                    return new Size(w, h);
                // irrelevant variable-length packets
                default:
                    int len=ReadBEUshort(rdr);
                    stream.Position+=len-2;
                    break;
            }
        }
    } finally {
        if(rdr!=null) rdr.Close();
        if(stream!=null) stream.Close();
    }
}

private static ushort ReadBEUshort(BinaryReader rdr) {
    ushort hi=rdr.ReadByte();
    hi<<=8;
    ushort lo=rdr.ReadByte();
    return (ushort)(hi|lo);
}
Run Code Online (Sandbox Code Playgroud)

这不是我的代码,在代码项目中得到这个例子.我复制并保存到我的实用程序片段,但不记得链接了.

  • 啊!大声笑.哇,这就是很多代码.再加上我在网络环境中,所以我也可能有GIF和png.我倾向于缓存Image.FromFile("cat.jpg").大小 - 或至少计算读取图像所需的时间 (2认同)

sho*_*osh 3

执行此操作通常涉及实际打开文件并仅读取其标头(前几个字节)以查找其格式和大小。您无需阅读整个文件即可了解其大小。有时,大小甚至位于文件中的特定偏移量中,因此查找大小仅读取 8 个字节。

您可以使用filemon.exe来实际了解 Windows 资源管理器本身如何查找大小。