5

我是 C# 的新手。因此,我不太确定我的程序有什么问题。该程序适用于小图像,但当它适用于大约 A4 大小的大图像时,它会显示“内存不足异常”。但是,如果不能处理大图像,该程序将毫无用处。我该如何解决这个问题?感谢。

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); 
        }
    }
}
4

3 回答 3

9

这是一张 9992x8750 的图片

是的,您处于 32 位进程的危险区域。该图像需要一大块连续的地址空间,334 兆字节。当您在程序启动后尽早加载图像时,您会很容易地得到它。那时你可以获得大约 650 兆字节,给予或接受。

但是当你的程序分配和释放内存并加载几个程序集时,这会从那里走下坡路。地址空间变得碎片化,分配之间的漏洞越来越小。仅仅用一个笨拙的基地址加载一个 DLL 就可以突然将最大的洞减少两倍以上。问题不在于可用的虚拟内存总量,它可以是千兆字节或更多,而是最大可用块的大小。一段时间后,90 兆字节的分配失败并不完全不寻常。只是一个分配可能会失败,您仍然可以分配一堆,比如说,50 兆字节的块。

地址空间碎片无法治愈,您无法修复 Bitmap 类存储像素数据的方式。但是,将 64 位版本的 Windows 指定为您的程序的要求。它提供大量虚拟内存,碎片不是问题。如果您想追查它,那么您可以使用 SysInternals 的VMMap 实用程序深入了解 VM 布局。当心您可能遇到的信息过载。

于 2012-07-19T10:36:34.493 回答
0

我怀疑您的主要问题是您同时使用了许多位图和图形实例。

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

于 2012-07-19T09:39:03.630 回答
0

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

于 2012-10-31T08:21:12.430 回答