jo_*_*ura 5 .net c# exception bitmap out-of-memory
我正在使用大尺寸图像(例如16000x9440像素)并剪切一些区域以用于其他事物.我在创建一个新的Bitmap实例时遇到异常"Out of memory":
using (FileStream fileStream = new FileStream(mapFileResized, FileMode.Open))
{
byte[] data = new byte[fileStream.Length];
fileStream.Read(data, 0, data.Length);
using (MemoryStream memoryStream = new MemoryStream(data))
{
using (Bitmap src = new Bitmap(memoryStream)) // <-- exception
{
tile = new Bitmap(tileWidth, tileHeight, PixelFormat.Format24bppRgb);
tile.SetResolution(src.HorizontalResolution, src.VerticalResolution);
tile.MakeTransparent();
using (Graphics grRect = Graphics.FromImage(tile))
{
grRect.CompositingQuality = CompositingQuality.HighQuality;
grRect.SmoothingMode = SmoothingMode.HighQuality;
grRect.DrawImage(
src,
new RectangleF(0, 0, tileWidth, tileHeight),
rTile,
GraphicsUnit.Pixel
);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
当我使用小图像尺寸(例如8000x4720像素)时,一切正常.
我如何处理大尺寸图像?
PS tile位图在finally块中处理.
最好的问候,Alex.
你正在使用大约一千兆字节的内存,并不是你内存不足的惊喜.
假设您使用具有16000x9440像素的32bpp文件格式,您将获得大约的文件大小:
16000*9440*(32/8)= ~576MB
byte[] data = new byte[fileStream.Length];
fileStream.Read(data, 0, data.Length);
using (MemoryStream memoryStream = new MemoryStream(data))
{
[... snip ...]
}
Run Code Online (Sandbox Code Playgroud)
您将整个文件加载到内存流中,这需要576MB.
[... snip ...]
using (Bitmap src = new Bitmap(memoryStream)) // <-- exception
{
[... snip ...]
}
[... snip ...]
Run Code Online (Sandbox Code Playgroud)
您将整个流内容加载到位图中,这至少需要另外576MB(取决于每个像素位图需要多少内存,应该至少为4,可能更多).那时你的内存中有两次图像会严重伤害这些大图像.
您可以通过删除内存流并直接从文件流加载位图来减少内存占用.
另一个解决方案是只加载位图的一部分并按需加载其他部分(很像谷歌地图),但我无法帮助你解决这个问题,可能需要手动读取位图.
归档时间: |
|
查看次数: |
5759 次 |
最近记录: |