4

I am trying to figure out a way to crop large TIFF images in .NET. Specifically, I am trying to do this operation on a GeoTiff, a TIFF that allows georeferencing information to be embedded within itself. For those unfamiliar with this type of dataset, it is fully compliant with TIFF 6.0 and is usually huge in size; many times in the gigabyte range.

I've been messing around with the System.Windows.Media.Imaging namespace to try to accomplish this task. However, the size of the tiff to be cropped causes out of memory errors. Can anyone point me to some information showing how to crop an image without reading input image into memory at the onset?

FYI - I am fully aware that GDAL is more than capable for this task. However, without getting into unecessary details, deploying GDAL with my app is not an option at this point for several reasons, hence my desire to do this with native .NET classes. However, if there are other 3rd party .NET libraries that could be of use, I'm all ears.

user163757
  • 6,795
  • 9
  • 32
  • 47
  • http://stackoverflow.com/questions/9004149/open-huge-tif-in-net-and-copy-parts-to-new-image/9009999#9009999 I solve my problem follow this answer. – Cryeyes Apr 09 '12 at 08:08

3 Answers3

3

Have a look at libtiff. You want to load the image by scanlines (or by strips, if that's how the image is formatted). Obviously, you still need enough memory to hold an entire scanline (or strip), but it's way more feasible than loading the entire image into memory.

There seems to be a .NET version of the library, and it looks like it's free and open source (unlike some of their other apps).

mpenkov
  • 21,621
  • 10
  • 84
  • 126
  • Also, note that some TIFF images use tile-based encoding, which is more efficient for very large-dimension images than strips as only the content of a tile can be decoded rather than a full strip. Libtiff makes it fairly easy to work at the strip- and tile-levels, but even so, a little familiarity with the structure of the TIFF container doesn't hurt. See the [TIFF 6.0 specification](http://partners.adobe.com/public/developer/tiff/index.html) – allonym Feb 14 '11 at 09:15
1

Unfortunately, the built-in GDI+ based imaging operations (available within System.Drawing and System.Drawing.Imaging require that the full image be loaded into memory at some point. This is obviously not feasible in your situation.

Adam Robinson
  • 182,639
  • 35
  • 285
  • 343
1

There's no way you should be considering a TIFF in the gigabyte range an 'image': treat it as a file on disk, or mapped into memory, and perform operations on it as if it were a dataset.

The Imaging Namespace isn't designed for such large datasets, it's for working with pictures, smaller images and so on. You'll have to either find a TIFF manipulation library or write your own routines to work at the file-level. There is an open-source C-based library called 'libtiff' I have worked with in the past; it could be a good starting point.

(Some difficulties you would face writing your own include the fact that TIFF files can have all kinds of compression - if it's geotechnical then maybe there's a standard / straightforward compression, or it's uncompressed? In which case copying memory around will be most of the work - that and preserving TIFF directories and entries. I would suggest taking a look at Atalasoft's DotImage library if you're after a commercial option.)

Kieren Johnstone
  • 41,277
  • 16
  • 94
  • 144