Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在不加载图像的情况下在.NET中可靠地获取图像尺寸?_.net_Image - Fatal编程技术网

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

如何在不加载图像的情况下在.NET中可靠地获取图像尺寸?,.net,image,.net,Image,我知道如何获得图像的大小(x,y) Image.FromFile("cat.jpg").Size 但这需要从内存中加载图像 当我在Windows资源管理器中查看图像时,它会显示图像的大小 我如何获得该尺寸 它对所有图像都可靠吗?Windows资源管理器是否需要先“查看”图像才能获得可用的大小。在将元数据加载到internet explorer之前,我不想将其上载到服务器并且没有可用的元数据 编辑:我将主题从“大小”更改为“尺寸”,以明确我想要的大小。这样做通常需要实际打开文件并仅读取其标题

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

Image.FromFile("cat.jpg").Size
但这需要从内存中加载图像

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

  • 我如何获得该尺寸
  • 它对所有图像都可靠吗?Windows资源管理器是否需要先“查看”图像才能获得可用的大小。在将元数据加载到internet explorer之前,我不想将其上载到服务器并且没有可用的元数据

编辑:我将主题从“大小”更改为“尺寸”,以明确我想要的大小。

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


您可以使用来实际查找windows资源管理器本身如何查找大小。

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

这里有一个现成的方法供您使用:)

公共静态大小GetJpegImageSize(字符串文件名){
FileStream=null;
BinaryReader rdr=null;
试一试{
stream=File.OpenRead(文件名);
rdr=新的二进制读取器(流);
//继续读取数据包,直到找到包含大小信息的数据包
对于(;;){
字节码=rdr.ReadByte();
如果(代码!=0xFF)抛出新的ApplicationException(
“文件中的意外值”+文件名);
code=rdr.ReadByte();
开关(代码){
//填充字节
案例0xFF:
溪流位置--;
打破
//无数据包
案例0xD0:案例0xD1:案例0xD2:案例0xD3:案例0xD4:
案例0xD5:案例0xD6:案例0xD7:案例0xD8:案例0xD9:
打破
//具有大小信息的数据包
案例0xC0:案例0xC1:案例0xC2:案例0xC3:
案例0xC4:0xC5:0xC6:0xC7:
案例0xC8:0xC9:0xCA:0xCB:
案例0xCC:0xCD:0xCE:0xCF:
ReadBEUshort(rdr);
ReadByte();
ushort h=ReadBEUshort(rdr);
ushort w=ReadBEUshort(rdr);
返回新尺寸(w,h);
//无关变长数据包
违约:
int len=ReadBEUshort(rdr);
流位置+=len-2;
打破
}
}
}最后{
如果(rdr!=null)rdr.Close();
如果(stream!=null)stream.Close();
}
}
专用静态ushort ReadBEUshort(二进制读取器rdr){
ushort hi=rdr.ReadByte();
您好您可以只使用“false”第2和第3个参数,以避免将文件加载到内存中。

本文提供了几种解决方案:

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

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

      Windows explore不是直接进入操作系统,询问映像在磁盘上分配了多少空间吗?它不是文件属性吗?或者正如你说的是编码元数据吗?@panix-如果我把你弄糊涂了,很抱歉。我的意思是大小如w所示idth+高度,而不是字节大小。@shy你知道资源管理器是这样做的吗?我可以依赖windows资源管理器的元数据吗?我只是觉得在一些wierd edge的情况下这有点狡猾,可能不可靠-这就是我发布question@Simon:是的,标题数据可能会欺骗您,但不是,除了读取t之外,没有其他方法他正在阅读整个文件。啊!哈哈。哇,这是很多代码。加上我在一个网络环境中,所以我可能也有GIF和PNG。我倾向于缓存Image.FromFile(“cat.jpg”).Size-或至少计时读取图像所需的时间Yep-它打开jpg以读取包含大小信息的标题这正是我需要的;无需字节管理等。谢谢!
      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);
      }