2012-07-19 46 views
5

我是C#的新手。 因此,我不太确定我的程序有什么问题。 该程序适用于小图像,但在与大小约为A4尺寸的大图像一起使用时,会显示“Out of memory exeception”。 但是,如果程序无法处理大图像,该程序将毫无用处。 我该如何解决这个问题? 谢谢。C中的内存不足异常#

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Drawing; 
using System.Drawing.Drawing2D; 
using System.Drawing.Imaging; 


namespace ConsoleApplication6 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      //Bitmap objects 

      //input image 
      Bitmap bmOrg = (Bitmap)Bitmap.FromFile(@"C:\B.png"); 
      Bitmap bmTransparentLayover = new Bitmap(bmOrg.Width, bmOrg.Height); 

      //Create Graphic Objects. 
      Graphics gOriginal = Graphics.FromImage(bmOrg); 
      Graphics gTransparentLayover = Graphics.FromImage(bmTransparentLayover); 

      //Set Transparent Graphics back ground to an "odd" color 
      //  that hopefully won't be used to 
      //Be changed to transparent later. 
      gTransparentLayover.FillRectangle 
           (Brushes.Pink, 
            new Rectangle 
            (0, 
            0, 
            bmTransparentLayover.Width, 
            bmTransparentLayover.Height 
           ) 
           ); 

      //Draw "transparent" graphics that will look through 
      // the overlay onto the original. 
      //Using LimeGreen in hopes that it's not used. 

      Point[] points = new Point[5]; 
      points[0] = new Point(130, 140); 
      points[1] = new Point(130, 370); 
      points[2] = new Point(420, 370); 
      points[3] = new Point(420, 140); 
      points[4] = new Point(130, 140); 
      System.Drawing.Drawing2D.GraphicsPath gp = new 
      System.Drawing.Drawing2D.GraphicsPath(); 
      gp.AddPolygon(points); 
      gTransparentLayover.FillPath(Brushes.LimeGreen, gp); 

      //Now make the LimeGreen Transparent to see through overlay. 
      bmTransparentLayover.MakeTransparent(Color.LimeGreen); 

      //draw the overlay on top of the original. 
      gOriginal.DrawImage(bmTransparentLayover, 
      new Rectangle(0, 0, bmTransparentLayover.Width, bmTransparentLayover.Height)); 

      //Create new image to make the overlays background tranparent 
      Bitmap bm3 = new Bitmap(bmOrg); 
      bm3.MakeTransparent(Color.Pink); 

      //Save file. 
      //to save the output image 
      bm3.Save(@"save.png",System.Drawing.Imaging.ImageFormat.Png); 

      Image img = new Bitmap(480, 480); 

      //the background image 
      img = Image.FromFile(@"a.png"); 
      Graphics g = Graphics.FromImage(img); 

      //to save the combined image 
      g.DrawImage(Image.FromFile(@"save.png"), new Point(-50, -70)); 
      img.Save(@"final.png", ImageFormat.Png); 
     } 
    } 
} 
+0

无关回答你的问题,你必须知道你必须关闭和处理你的图形对象。使用'using'语句填充代码段。那会做这项工作。 – 2012-07-19 08:21:34

+5

A4大小不会说什么。我可以创建一个只有4个像素的A4尺寸图像:) – 2012-07-19 08:21:38

+0

不确定问题所在,但是尝试在实现IDisposable(位图,图形)的每个对象周围添加使用语句。 当您查看任务管理器时,进程使用多少内存? – Maarten 2012-07-19 08:22:32

回答

0

我怀疑你的主要问题是你有一些位图和图形实例在同一时间使用。

可能值得尝试重新组织代码,以便尽可能少地使用这些代码,使用.Dispose()删除已完成的项目。

8

它是一个9992x8750的图像

是的,你在一个32位过程中的危险区域是。该映像需要大量的连续地址空间,334兆字节。在程序启动后尽早加载图像时,您会轻松获得该图像。在这一点上,你可以获得大约650兆字节。

但是,随着程序分配和释放内存并加载几个程序集,该程序会从那里进入下坡。地址空间分散,分配之间的空洞变小。只需加载一个具有尴尬基地址的DLL就可以突然将最大的空洞减少一倍以上。问题不在于可用虚拟内存的总量,它可能是千兆字节或更多,它是最大可用块的大小。一段时间后,90兆分配失败并不是完全不寻常的。只要一个分配可能会失败,你仍然可以分配一堆,比如50兆字节块。

无法解决地址空间碎片问题,也无法修复Bitmap类存储像素数据的方式。但是,您需要指定64位版本的Windows作为您的程序需求。它提供了虚拟内存,碎片化并不是问题。如果你想追赶它,那么你可以通过SysInternals'VMMap utility了解VM布局。谨防你可能遇到的信息超载。

0

尝试在Windows 64位上工作,这是大多数内存问题的解决方案。