开发者

(C#) graphics.drawImage has a size limit? How to deal with it?

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开发者_如何学Python?)


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).


You will run into a problem long before you reach this limit, around about 10000x10000 pixels you will be using up nearly all your memory for your bitmap. Consider the internal gdi+ bitmap will be 32bppargb you are looking at 4 bytes per pixel x 100000000 = 4GB by my calculation.

You should break the image down into tiles, or if you are drawing this manually implement a paging solution.


I have been able to build bitmaps up to 25200 by 15000 pixels using C# and Windows Forms in a 64 bit application. System has 64 Gig of Ram and NVIDIA GeForce GTX 1070 with 8GB of GDDR5.

I'm still experimenting but it seems that this is about the limit on bitmap size. I'm porting my apps to WPF and have gotten large images there as well.

It's true that there is no way to display these images on a monitor but but they can be saved to files and sent to a commercial printer. I'm using this to make high res prints of generative art.

See examples here: https://www.facebook.com/search/top?q=dr%20tom%20fernandez%20art

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜