0

I have an List as such

List<Bitmap> imgList = new List<Bitmap>();>

i need to scroll through that list, very quickly and stitch all the images into one. Like so

using (Bitmap b = new Bitmap(imgList[0].Width, imgList[0].Height * imgList.Count, System.Drawing.Imaging.PixelFormat.Format24bppRgb))
        {
            using (Graphics g = Graphics.FromImage(b))
            {
                for (int i=0;i<imgList.Count;i++)
                {
                    g.DrawImage(imgList[i], 0, i * imgList[i].Height);
                }
            }
            b.Save(fileName, ImageFormat.Bmp);

        }
        imgList.Clear()

The problem that i'm running into is that the images are 2000 wide by 2 high, and there could be 30,000-100,000 images in the array. When I try to make a blank bitmap that size, it get a parameter not found error. Any help would be GREATLY appreciated.

  • With 100k images, each of which is 4k pixels, the 24bpp image that you're trying to create may simply be too large. See this for details: http://stackoverflow.com/questions/6333681/c-sharp-parameter-is-not-valid-creating-new-bitmap – wablab Oct 20 '16 at 16:35
  • What is the average size of the images? How "big" will be the image after processing? – Cadburry Oct 20 '16 at 16:39
  • http://stackoverflow.com/questions/465172/merging-two-images-in-c-net – Vivek Nuna Oct 20 '16 at 16:41
  • They images in the list are 2000x2 and the list can be between 30,000 and 100,000 items. I certainly agree that i'm running into memory error, i just don't know how to fix it. – user7049117 Oct 20 '16 at 16:44
  • Puhh.. Which application can read/load that afterwards... I dont know your task.. But by using this approach via .net with gdi api this is a hard task... Is there not a different way? (Resizesing before... A fwe "larger" images) – Cadburry Oct 20 '16 at 16:54
  • It is barely possible, but not in a 32-bit process. Remove the jitter forcing. Project > Properties > Build tab, untick "Prefer 32-bit" when you see it, Platform target = AnyCPU. Repeat for the Release configuration. – Hans Passant Oct 20 '16 at 17:07
  • @viveknuna : The `List` class is actually built on top of an array. – Visual Vincent Oct 20 '16 at 17:39

1 Answers1

1

The size of the block of memory you need is 2 x 100,000 x 20,000 x # bytes per pixel, which is going to be either 12,000,000,000 bytes for 24 bits per pixel and 16,000,000,000 bytes for 32 bits per pixel. So in other words ~12GB or ~16GB. A 32 bit address space is just too darn small for that amount of memory, so sucks to be you.

Or does it?

Since you want to create a file from this, you should be concerned with the file limits rather than your own memory limits. Lucky for you, the size of the integer type used for image dimensions in a BMP is 32 bit, which means that a 200,000 x 2,000 image is totally within those limits. So whether or not you can make that image in memory, you can make the file.

This involves you making your own version of a BMP encoder. It's not that bad - it's most writing a BMP header, a DIB header (110 bytes total) and then raw pixel data. Of course, once done you'll be hard-pressed to find code that will open it, but that's someone else's problem, right?

plinth
  • 48,267
  • 11
  • 78
  • 120
  • You are off by 10, it is x 2000, not x 20000. 1.6 GB is not a problem in a 64-bit process, 2 GB is the hard upper limit for a GDI+ bitmap. – Hans Passant Oct 20 '16 at 18:05
  • I would be looking at using a Tile Tiff file, as there are apps that can read VERY large images from them. – Ian Ringrose Oct 20 '16 at 18:37
  • TIFF is indeed a possibility since TIFF itself can encode in bands. Writing a correct TIFF encoder is substantially more challenging and fraught with error. – plinth Oct 21 '16 at 12:54