0

According to this -> https://social.msdn.microsoft.com/Forums/vstudio/en-US/58710bdd-4832-4531-a50a-b83a7e733cdd/maximum-size-of-a-writeablebitmap-systemwindowsmediaimagingwritablebitmap?forum=wpf

The maximum height and width of an image is 2^16 pixels at 32 bits per channel * 4 channels. The maximum size of a BitmapSource is 2^32 bytes (64 gigabytes) >and the maximum image size is four gigapixels. The minimum image size is 1x1.

The max size is (2^16)^2 = 4,294,967,296 pixels

Each pixel is 4 bytes per channel, and with four channels (A/R/G/B), that’s 16 bytes.

So the max size in bytes would be 16 * 4,294,967,296 = 68,719,476,736 bytes = 64 gigabytes.

However, I'm only able to go as high as

System.Windows.Media.Imaging.WriteableBitmap wbit = new WriteableBitmap(32000, 32000, 97, 97, PixelFormats.Bgra32, null);

If I go higher, for example to 33,000 x 33,000, the constructor throws a System.OverflowException: The image data generated an overflow during processing. ---> System.ArithmeticException: Overflow or underflow in the arithmetic operation.

My computer has 32GB of memory, running Windows 8.1, VS , and this is a .NET 4.5 console application, targeting 64-bit platform, and gcAllowVeryLargeObjects has been enabled in App.Config so this is not a problem related with .NET Maximum Object Size of 2GB. I can create an array of integers as large as 15GB in this application.

Additionally, I'm referencing PresentationCore, PresentationFramework, and WindowsBase to get access to WIC, which are all located inside C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5\ which alarmed me at first because it was in the x86 directory but as I understand it, these are only used to retrieve metadata, and the real assemblies actually being used are in the GAC, so for example, in Windows 8.1 Pro, there is both 32bit and 64bit PresentationCore are at C:\Windows\assembly\NativeImages_v4.0.30319_32\PresentationCore\24f6c80242420a1cea5cc254bf420027 and at C:\Windows\assembly\NativeImages_v4.0.30319_64\PresentationCore\7a22d69ccf672cec14abf04d9551b3a0 respectively. Same type of deal goes for PresentationFramework and WindowsBase, and I'm not 100% on this, but I think application is probably using the 64-bit versions of these assemblies in the GAC even though the reference assemblies in the reference assemblies directory are being referenced.

Does anyone know how I can construct a WriteableBitmap at its maximum resolution of 2^16 which is 65,536 x 65,536 or what I am doing wrong?

Seong Yup Yoo
  • 335
  • 1
  • 3
  • 11
  • Your reference might be incorrect. In any case, it says the max resolution for an image is 2^16; I wouldn't be surprised (especially given the behavior you're reporting) if that really means the coordinate system is 16 bits, putting the actual maximum size at `2^15 - 1`, which is 32767. So a 32000x32000 image would be legal, but a 33000x33000 would not. Do you have an _official_ reference that suggests to you that you should be able to create a larger bitmap than 32767x32767? – Peter Duniho Mar 21 '15 at 15:17
  • @PeterDuniho You're right. 32767 works, but 32768 does not. I don't have any official reference that says that. Nothing in the WriteableBitmap's official documentation. I was going off of that MSDN forum post. I wonder why they wasted a bit on using a signed integer, and I wonder if there is a way around this to get up to 65,536 x 65,536 coordinates. – Seong Yup Yoo Mar 21 '15 at 15:29
  • I doubt the designers of the API consider the bit wasted, as it's likely the 16-bit data size starts with a coordinate system (where negative coordinate values are permitted), and then that same coordinate system is the basis for bitmap dimensions (where negative values don't make sense). I.e. the bit is wasted only in the bitmap size scenario, but not more generally. I doubt you can bypass this in the API, but of course you could always tile four 32767x32767 bitmaps (getting you to 65534x65534). – Peter Duniho Mar 21 '15 at 15:32
  • Hmya, don't believe anything you read on the MSDN forums. I suspect that the engineer documented a WIC limitation. But .NET uses an extra api layer inbetween called MILCore. The function that fails is MILSwDoubleBufferedBitmapCreate(). Very little is known about MILCore, it was a one-off project for WPF, it isn't used anywhere else in Microsoft software and is completely undocumented. The group that supported it considers it legacy today and moved on. You'll need to deal with what you've learned to be accurate, MILCore does appear to have a built-in hard 4 GB limit upper limit. – Hans Passant Mar 21 '15 at 16:42
  • I see. Thanks. Tiling 4 works for me in terms of just working with the images, but not so much in the end, as I actually want to produce a single JPG or PNG of that size. Although, now I'm having trouble trying to save even a 32767 x 32767 image as it's throwing an AccessViolationException: attempted to read or write protected memory. It works fine up to 23,000 x 23,000, but breaks for 24,000 x 24,000. I'm guessing this is now a limitation of the PngBitmapEncoder I'm using. Thank you for pointing out the exact limitation of the WriteableBitmap class. – Seong Yup Yoo Mar 21 '15 at 16:48
  • WIC supports more formats than GDI+ such as 16-bit Gray and 32-bit Float. The issue is that the array that such methods as WriteableBitmap.WritePixels and other API calls is still limited to a 2GB standard System.Array in C#. Basically the same as GDI+. I did a bunch of testing and 24bpp RGB and 32bpp RGBA WIC images are limited to square aspect of 26754x26754, 16-bit Gray WIC images are limited to 32767x32767, and 8-bit Gray WIC images are limited to 46329x46329. – deegee Jan 15 '21 at 16:03
  • I did some further testing of the maximum WIC image sizes and this is the results. The maximum bitmap array size is 2GB for any WIC image format. The C# array index range is 0 to 0x7FFFFFC7 (2,147,483,591). So to determine the maximum square dimensions of any WIC format, simply take the square root of the index range divided by the bytes per pixel (eg 24-bit = 3 bytes). 8-bit 256 Color Indexed = 46340 × 46340; 8-bit Gray = 46340 × 46340; 16-bit Gray = 32767 × 32767; 24-bit RGB = 26754 × 26754; 32-bit RGBA = 23170 × 23170; 48-bit RGB = 18918 × 18918; 64-bit RGBA = 16383 × 16383. – deegee Oct 29 '21 at 21:52

0 Answers0