2009-02-16 30 views
21

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

Image.FromFile("cat.jpg").Size 

的大小(X,Y),但是这需要从内存中加载图像。

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

  • 如何获得该尺寸?
  • 它是可靠的所有图像? Windows资源管理器需要首先“看到”图像才能使用该尺寸。我不想上传到服务器,并且在将它加载到Internet Explorer之前没有可用的元数据。

编辑:我改变从“大小”的主题为“尺寸”澄清我想其大小。

回答

3

这样做通常涉及实际打开文件并只读取其标题(前几个字节)以查找其格式和大小。你不需要阅读整个文件来找出它的大小。有时候,文件的大小甚至会在文件的特定偏移量中找到,因此查找大小只能读取8个字节。

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

+0

不要Windows探索去权限操作系统,因为问问图像在磁盘上分配了多少空间?它不是文件属性吗?或者正如你所说,它是编码元数据? – Paxic 2009-02-16 07:31:41

+0

@panix - 对不起,如果我困惑你。我的意思是宽度+高度的大小,而不是字节的大小。 – 2009-02-16 07:34:47

+0

@shy你知道这是探险家吗?我可以依靠Windows资源管理器的元数据吗?我只是觉得这有些鬼鬼祟祟,在一些奇怪的边缘情况下可能不可靠 - 这就是为什么我发布了问题 – 2009-02-16 07:35:40

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); 
} 

这不是我的代码,得到这个例子一段时间回来代码项目。我复制并保存到我的实用程序片段,但不记得链接。

1

从我的头顶 - LoadImage()有一个指定进度回调的覆盖。也许你可以使用它来取消标题读取后的加载?

相关问题