读取tiff文件的尺寸和分辨率,而不需要先加载它

9
如何在不加载到内存中的情况下读取tiff文件的尺寸(宽度和高度)和分辨率(水平和垂直)?以下代码太慢了,对于大文件来说不可行,而且我不需要操作它们。请帮忙改进。
Image tif = Image.FromFile(@"C:\large_size.tif");
float width = tif.PhysicalDimension.Width;
float height = tif.PhysicalDimension.Height;
float hresolution = tif.HorizontalResolution;
float vresolution = tif.VerticalResolution;
tif.Dispose();

编辑:

那些tiff文件是双色的,尺寸为30x42英寸。文件大小约为1-2 MB。因此,上述方法可行但速度较慢。

4个回答

12

我自己遇到了这个问题并且找到了解决方案(可能在这里)。Image.FromStream使用validateImageData = false,可以让你访问所需的信息,而不必加载整个文件。

using(FileStream stream = new FileStream(@"C:\large_size.tif", FileMode.Open, FileAccess.Read))
{
  using(Image tif = Image.FromStream(stream, false, false))
  {
    float width = tif.PhysicalDimension.Width;
    float height = tif.PhysicalDimension.Height;
    float hresolution = tif.HorizontalResolution;
    float vresolution = tif.VerticalResolution;
  }
}

刚看到你的评论。我尝试了一下,你是对的。这个方法比我原来提出问题时使用的那个方法要快得多。谢谢。 - z1x2
这个 Image 是从哪里来的? - Daniel Möller
System.Drawing.Image - Joel Rondeau

2
据我所知,System.Drawing 命名空间中的所有类在打开图像时立即加载图像数据。
我认为 LibTiff.Net 可以帮助您读取图像属性而无需加载图像数据。它是免费且开源的(BSD 许可证,适用于商业应用程序)。
以下是一个针对您任务的示例(为简洁起见省略了错误检查):
using BitMiracle.LibTiff.Classic;

namespace ReadTiffDimensions
{
    class Program
    {
        static void Main(string[] args)
        {
            using (Tiff image = Tiff.Open(args[0], "r"))
            {
                FieldValue[] value = image.GetField(TiffTag.IMAGEWIDTH);
                int width = value[0].ToInt();

                value = image.GetField(TiffTag.IMAGELENGTH);
                int height = value[0].ToInt();

                value = image.GetField(TiffTag.XRESOLUTION);
                float dpiX = value[0].ToFloat();

                value = image.GetField(TiffTag.YRESOLUTION);
                float dpiY = value[0].ToFloat();
            }
        }
    }
}

免责声明:我是这个库的维护者之一。

感谢您提供代码。我认为LibTiff.Net可能是非商业用途中唯一的开源选择。我的程序只有不到30k的小型单一程序。处理tiff文件并不是它的主要任务。因此,现在我更倾向于坚持使用当前缓慢但简单的解决方案。 - z1x2

1

试试this,它似乎是你正在寻找的东西。只需跳过冒号后面的所有内容即可。

TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, ref w); //your width
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, ref h); //your height
TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, ref bits);
TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, ref samples);

别忘了在完成后关闭:

TIFFClose(tif);

我找到了一个部分解决方案,使用Shell32.Folder.GetDetailsOf()。但是在Windows XP上它只能获取尺寸而不能获取分辨率。谢谢。 - z1x2

1

我能想到的唯一方法是读取tiff二进制头。

你可以在这里下载规范:http://partners.adobe.com/public/developer/tiff/index.html

以下是用于读取Tiffs的一些代码,你可以用来学习: http://www.koders.com/csharp/fidF6632006F25B8E5B3BCC62D13076B38D71847929.aspx?s=zoom

我之前创建了一个库来读取tiff头部(以这两个资源为基础),但它是我雇主的代码的一部分,所以我不能在这里发布我的代码,而且我可以说它并不难。

希望这对你有所帮助。


谢谢您指引我正确的方向。我大致阅读了这两个链接上的材料。但是现在我犹豫是否要花时间从头开始创建解决方案,因为我在位级编程方面没有太多经验。 - z1x2
在完成项目之前,我将尝试使用WPF图像组件。我可能会利用您提供的信息,在自己的时间里编写练习的解决方案。 - z1x2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接