I am attempting to display a very large graphical representation of some data. I am using a bitmap for persistent storage of the image and e.Graphics.DrawImage(myBitmap, new Point(0,0))
in the onPaint of a PictureBox control on my form. I have noticed (and heard mentioned on other sites) that if my image has a height or width greater than 2^15, I get a Parameter not Valid
exception, but I have not found any official documentation of this limit.
Is this 2^15 image size limit a definite, official part of Graphics.DrawImage
? Are there any simple workarounds to render my entire image onto the form?
(Yes, the pictureBox is set to the same size as the image, or bigger. Side question though, should I just be using the onPaint of the form itself instead of a picture box?)
You have a few issues here. First, it's not fundamentally possible to display an image this large (unless you have some sort of insanely huge monitor or multiple monitor setup) without shrinking it down to a size that will fit on a normal screen.
You can perform this size reduction using Graphics.DrawImage
, but keep in mind that even with a high-quality InterpolationMode
, the interpolation is only done on at most a few neighboring pixels, which means there is a limit to the maximum amount you can reduce an image without serious loss of information (usually down to 25%).
Second, a Bitmap
object in .Net is a lot more complicated than just a simple array of pixels. Bitmaps are sometimes created in video RAM instead of general program memory, which limits their maximum size more severely (in the compact framework, as one example, one of the Bitmap constructors creates the pixel data in video RAM, which is limited to 4MB instead of the 32MB normally available to a .NET process). As a result, there is no documented maximum size for a Bitmap
- this is an internal implementation detail (affected as well by any already-existing bitmaps) that a programmer can only discover the hard way, by getting a thrown exception if it's too big. So using a Bitmap
to store an arbitrarily large set of data points is not going to work.
Your best approach here would probably be to store your data as an ordinary two-dimensional array (of type int[,]
, probably), which could be arbitrarily large without throwing an OutOfMemoryException
(although not without making your computer go swapfile-crazy), and then write a custom method that copies from this array into an actual (and practically-sized) Bitmap
. You would then copy from this Bitmap
to your PictureBox
(or, more simply, just set this Bitmap
as the picture box's Image
property - it's best to avoid the Paint
method whenever possible).