4

This is for a .NET 4.5 Console Application running on a 64-bit Windows 8 system with 32GB of memory. The application is targeted for 64-bit platforms and has the gcAllowVeryLargeObjects flag enabled, which allows the application create objects larger than .NET limit of 2Gb. So, I am able to create an array of integers as large as 15GB.

I create a 32,767 by 32,767 pixel System.Windows.Media.Imaging.WriteableBitmap which uses WIC (Windows Imaging Component and not GDI+ as WIC can handle higher resolution than GDI+) using the following constructor

WriteableBitmap wbit = new WriteableBitmap(32767, 32767, 300, 300, PixelFormats.Bgra32, null);

I have tried to save it as a JPG using following code

using (FileStream stream = new FileStream("c:\\test.jpg",FileMode.Create))
{
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(wbit));
encoder.Save(stream);
}

I have also tried to save it as a PNG using following code

using (FileStream stream = new FileStream("c:\\test.png",FileMode.Create))
{
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(wbit));
encoder.Save(stream);
}

For both JPG and PNG, I can go up to 23,170 x 23,170 resolution, and it work fine, but going up to 23,171 x 23,171 throws the following exception

System.AccessViolationException: Attempted to read or write protected memory. Tis is often an indication that other memoryis corrupt. at MS.Wind32.PresentationCore.UnsafeNativeMethods.WICBitmapFrameEncode.WriteSource(SafeMILHandle THIS_PTR, SafeMILHandle pIBitmapSource, Int32Rect& r) at System.Windows.Media.Imaging.BitmapEncoder.Save(Stream stream)

Does anyone know the cause of this exception, and how I might be able to get around it so that I can save the full maximum resolution at 32,767 x 32,767? Maybe I have to use another encoder or even start looking outside .NET framework. I would ideally like to be able to work with images at the JPEG maximum resolution of 65,535 x 65,535, or even higher at 100,000 x 100,000 pixels in PNG. I would appreciate any help with this matter or suggestion towards the right direction. Thanks.

Seong Yup Yoo
  • 335
  • 1
  • 3
  • 11
  • "as WIC can handle higher resolution than GDI+" Where did you find that out? I could not find anything in the documentation about that. – Scott Chamberlain Mar 21 '15 at 19:34
  • @ScottChamberlain no documentation on any of these, it's based on my testing with Bitmap and WriteableBitmap past couple of days. Bitmap starts breaking at "around" 22000 x 22000 pixels, and it's not a hard number because its limit is based on the 2GB virtual memory limit. So, 22000 x 22000 sometimes works and sometimes doesn't. WriteableBitmap has a hard limit that goes up to 32,767 x 32,767, but always breaks at 32,768 x 32,768. See [this post](http://stackoverflow.com/questions/29175585/what-is-the-maximum-resolution-of-c-sharp-net-bitmap) – Seong Yup Yoo Mar 21 '15 at 19:42
  • Tiling is not an option? ie. Google Maps is not made up of one huge image either. – Caramiriel Mar 21 '15 at 19:45
  • I already do do the tiling, and do it afterwards to make the image available on the web afterwards like Goodle Maps, but before that phase, I still need to generate a single JPG or PNG file of the entire thing. – Seong Yup Yoo Mar 21 '15 at 20:06
  • I'm not an expert on the guts of the Microsoft API's, but the "Wind32" bit in the error is suspicious. It suggests that the encoder API is calling into 32-bit unmanaged code, which then falls over on your large images. If this is encoder-specific you could look for another encoder (BMP?) in the System.Windows.Media library. Alternatively, find a third party 64-bit encoder. (Would System.Drawing.Bitmap.Save do any better?) – yoyo Mar 21 '15 at 20:59
  • System.Drawing.Bitmap only goes up to around 22,000 x 22,000, So, even though if it saves at that resolution, it's lower than the limit I'm hitting with WriteableBitmap at 23,170 x 23,170 – Seong Yup Yoo Mar 21 '15 at 22:11

1 Answers1

-1

You're right about the JPEG format itself supporting higher resolutions. I tested using a huge JPEG image that's 40,000 x 33,000 pixels in size. The JPEG failed to load using System.Drawing.Bitmap, but it opened correctly using at least 2 different programs:

  1. Windows 7 Photo Viewer, probably because it uses WIC, not GDI+.
  2. IrfanView 64-bit, but it resized it to half-width and half-height during loading.

This indicates the test JPEG image was indeed valid even though GDI+ can't load it. Since this is not a limitation of the JPEG specification, it must be a limitation within Microsoft’s implementation. It’s unlikely there’s a work-around with their encoder here. If you must have a higher resolution (and you indicated you do), your best solution is likely to find a different library to do the encoding.

LEADTOOLS Support
  • 2,755
  • 1
  • 12
  • 12