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

wj8zmpe1  于 2023-06-25  发布在  .NET
关注(0)|答案(5)|浏览(116)

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

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

但这需要从内存中加载图像。
当我在Windows资源管理器中查看图像时,它会显示大小。

  • 我如何访问这个大小?
  • 它对所有图像都可靠吗?Windows资源管理器是否需要先“看到”该大小的图像才可用。我不想将我的图像上传到服务器,并且如果我从未打开该文件夹,则没有可用的元数据。
cbjzeqam

cbjzeqam1#

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

2guxujil

2guxujil2#

如果你想得到图像的尺寸(宽度和高度)与加载图像,你需要阅读一些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);
}

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

unguejic

unguejic3#

文章Reading Image Headers to Get Width and Height提供了几种可能的解决方案:

  • 多线程
  • 阅读文件头,如果缺少头,则恢复到完整的图像加载
  • 为图像属性创建自己的索引
kgqe7b3p

kgqe7b3p4#

这样做通常涉及实际打开文件并仅阅读其头(前几个字节)以查找其格式和大小。你不需要读取整个文件来确定它的大小。有时大小甚至在文件中的特定偏移量中,因此查找大小仅阅读8个字节。
你可以使用filemon.exe来实际了解windows资源管理器本身是如何查找大小的。

5jdjgkvh

5jdjgkvh5#

在我的脑海中-LoadImage()有一个指定进度回调的覆盖。也许你可以用它来取消头被读取后加载?

相关问题