【问题标题】:Read a tiff file's dimension and resolution without loading it first无需先加载即可读取 tiff 文件的尺寸和分辨率
【发布时间】:2010-10-29 00:32:30
【问题描述】:

如何使用如下代码读取 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 文件是 Bilevel,尺寸为 30x42 英寸。文件大小约为 1~2 MB。所以上面的方法可以,但是很慢。

【问题讨论】:

    标签: c# memory tiff


    【解决方案1】:

    我自己遇到了这个问题并找到了解决方案(可能在这里)。 Image.FromStreamvalidateImageData = 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;
      }
    }
    

    【讨论】:

    • 刚看到你的cmets。我试过了,你是对的。该方法比我原来的问题中使用的方法快得多。谢谢。
    • 这个Image来自哪里?
    • System.Drawing.Image
    【解决方案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 文件不是它的主要任务。所以现在我更喜欢坚持我目前缓慢但简单的解决方案。
    【解决方案3】:

    试试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 上只能获得尺寸而不能获得分辨率。谢谢。
    【解决方案4】:

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

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

    以下是一些用于阅读 Tiff 的代码,您可以使用它来学习: http://www.koders.com/csharp/fidF6632006F25B8E5B3BCC62D13076B38D71847929.aspx?s=zoom

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

    我希望这会有所帮助。

    【讨论】:

    • 感谢您为我指明正确的方向。我大致阅读了两个链接上的材料。但现在我犹豫是否要花时间从头开始创建解决方案,因为我在位到位级别的编程方面没有太多经验。
    • 在完成项目之前,我将为此尝试 WPF Imaging Component。我可能会使用您提供的信息来编写解决方案,以便在我自己的时间进行锻炼。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多