z1x2
z1x2

Reputation: 793

Read a tiff file's dimension and resolution without loading it first

How to read a tiff file's dimension (width and height) and resolution (horizontal and vertical) without first loading it into memory by using code like the following. It is too slow for big files and I don't need to manipulate them.

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

Edit:

Those tiff files are Bilevel and have a dimension of 30x42 inch. The file sizes are about 1~2 MB. So the method above works Ok but slow.

Upvotes: 9

Views: 16339

Answers (4)

Bobrovsky
Bobrovsky

Reputation: 14246

As far as I know, all classes from System.Drawing namespace load image data immediately when image is open.

I think LibTiff.Net can help you to read image properties without loading image data. It's free and open-source (BSD license, suitable for commercial applications).

Here is a sample for your task (error checks are omitted for brevity):

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

Disclaimer: I am one of the maintainers of the library.

Upvotes: 3

Joel Rondeau
Joel Rondeau

Reputation: 7586

Ran into this myself and found the solution (possibly here). Image.FromStream with validateImageData = false allows you access to the information you're looking for, without loading the whole file.

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

Upvotes: 12

Edgar Hernandez
Edgar Hernandez

Reputation: 4030

The only way I can think of is reading the tiff binary header.

Here you can download the specification: http://partners.adobe.com/public/developer/tiff/index.html

Here is some code used to read Tiffs that you can use to learn: http://www.koders.com/csharp/fidF6632006F25B8E5B3BCC62D13076B38D71847929.aspx?s=zoom

I created a library to read the tiff headers some time ago (with this two resources as base) but it was part of my employer code so I can't post my code here and I can say it is no really hard.

I Hope this helps.

Upvotes: 1

Onkelborg
Onkelborg

Reputation: 3997

Try this, it seems to be what you are looking for. Just skip everything after:

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

Don't forget to close after you:

TIFFClose(tif);

Upvotes: 1

Related Questions