windows (C#) graphics.drawImage 有大小限制吗?如何处理?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2596457/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
(C#) graphics.drawImage has a size limit? How to deal with it?
提问by DGH
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.
我试图显示一些数据的非常大的图形表示。我使用位图来持久存储图像,并e.Graphics.DrawImage(myBitmap, new Point(0,0))
在我的表单上的 PictureBox 控件的 onPaint 中使用。我注意到(并听说在其他网站上提到过)如果我的图像的高度或宽度大于 2^15,我会得到一个Parameter not Valid
例外,但我没有找到任何关于此限制的官方文档。
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?
这个 2^15 图像大小限制是确定的官方部分Graphics.DrawImage
吗?是否有任何简单的解决方法可以将我的整个图像渲染到表单上?
(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?)
(是的,图片框设置为与图像相同的大小,或者更大。不过,我应该只使用表单本身的 onPaint 而不是图片框?)
回答by MusiGenesis
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%).
您可以使用 执行此尺寸缩小Graphics.DrawImage
,但请记住,即使使用高质量InterpolationMode
,插值也最多只在几个相邻像素上完成,这意味着您可以在不严重的情况下缩小图像的最大数量是有限的信息丢失(通常下降到 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.
其次,Bitmap
.Net 中的对象比简单的像素数组复杂得多。位图有时在视频 RAM 中创建而不是在通用程序存储器中创建,这更严重地限制了它们的最大大小(在紧凑框架中,例如,位图构造函数之一在视频 RAM 中创建像素数据,限制为 4MB 而不是.NET 进程通常可用的 32MB)。因此,没有记录的 a 的最大大小Bitmap
- 这是一个内部实现细节(也受任何已经存在的位图影响),程序员只能通过困难的方式发现它,如果它太大,就会抛出异常。因此,使用 aBitmap
来存储任意大的数据点集是行不通的。
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).
您最好的方法可能是将您的数据存储为一个普通的二维数组(int[,]
可能是 类型),它可以是任意大的而不会抛出一个OutOfMemoryException
(尽管不会使您的计算机变得疯狂交换文件),然后编写一个从此数组复制到实际(和实际大小)的自定义方法Bitmap
。然后Bitmap
,您将从 this 复制到您的PictureBox
(或者,更简单地说,只需将其设置Bitmap
为图片框的Image
属性 - 最好尽可能避免使用该Paint
方法)。
回答by James Westgate
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.
在达到此限制之前很久,您就会遇到问题,大约 10000x10000 像素左右,您将用尽几乎所有的位图内存。考虑到内部 gdi+ 位图将是 32bpargb,根据我的计算,您正在查看每像素 4 个字节 x 100000000 = 4GB。
You should break the image down into tiles, or if you are drawing this manually implement a paging solution.
您应该将图像分解为图块,或者如果您正在手动绘制此图像,则实施分页解决方案。
回答by Thomas Fernandez
I have been able to build bitmaps up to 25200 by 15000 pixels using C# and windows forms in a 64 bit application. I'm still experimenting but it seems that this is about the limit on bitmap size.
我已经能够在 64 位应用程序中使用 C# 和 windows 窗体构建高达 25200 x 15000 像素的位图。我仍在试验中,但似乎这是位图大小的限制。