6

I need to process large images (20,000x20,000pixels) in C#. Opening these images directly isn't the way to go because of memory limitations, but what I want to do is split the image into smaller pieces (cropping). I was looking for a 3rd party library that could the trick, but so far no result. I tried FreeImage and ImageMagick, but they cannot open an 20,000x20x000 pixel image. How can I achieve this?

  • 1
    What format is the image in? In formats like bitmap you could just use file io directly. If you wish to use GDI or whatever, you would then convert the individual chunks to a stream and then load it into an image). Formats like PNG would require you to delve deeper, examinng how PNG files are split into blocks and working with them directly. – Brian Jun 19 '09 at 15:03

5 Answers5

3

My current project at work consists of an image viewer/analyzing program capable of loading images in excess of 16 gb. You have to use manual file IO, pull the header information out and create your subimages on-demand (or if you're processing the image, you can create a single tile and process it in-place). Very few libraries are going to give you the capability to load/modify a 20k by 20k image (1.2gb at 24bpp) and the ones that do will rarely do so with anything resembling performance (if that is a concern).

Ron Warholic
  • 9,994
  • 31
  • 47
1

Don't know if this would help, but here is an article on image processing with C# lambda expressions.

jjclarkson
  • 5,890
  • 6
  • 40
  • 62
1

I don't know of any existing library to do this.

You're probably going to have to crack open the image file stream, seek to location where the color and pixel data exists, and read a section of the pixel data into an array, and create your image from that.

For example, for the BMP file format, you'll want to seek into the color table, load the color table, then seek to the pixel array section, load however many pixes you wish into an array, then make a new bitmap with just those pixels.

Judah Gabriel Himango
  • 58,906
  • 38
  • 158
  • 212
1

You can use the built-in .Net libraries.

Use

sourceBitmap = (Bitmap)Image.FromStream(sourceFileStream, false, false);

That will stop the image data from being cached in memory. You can create a new destination bitmap to draw a subsection of that massive image to:

var output = new Bitmap(outputWidth, outputHeight);
var outputGraphics = Graphics.FromImage(output);

outputGraphics.DrawImage(sourceBitmap, destRect, srcRect, GraphicsUnit.Pixel);

using (var fs = File.OpenWrite(outputFilePath))
{
    output.Save(fs, System.Drawing.Imaging.ImageFormat.Png);
}

Where destRect can be the whole size of the outputImage, or a smaller area.

Kind Contributor
  • 17,547
  • 6
  • 53
  • 70
0

I'd do it with ImageMagick. There is a pretty solid .NET API available, and it is typically the best way to do image processing like this.

Look under .NET, part of the way down the page.

http://www.imagemagick.org/script/api.php

Here is the info on how the crop stuff in ImageMagick works, for the command line version.

http://www.imagemagick.org/Usage/crop/#crop

Matthew Kennedy
  • 616
  • 4
  • 19