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をロードするだけで、突然最大の穴を2倍以上削減できます。問題は、使用可能な仮想メモリの合計量ではなく、ギガバイト以上になる可能性があり、使用可能な最大のチャンクのサイズです。しばらくすると、90メガバイトの割り当てが失敗することはまったく珍しいことではありません。1つの割り当てが失敗する可能性があるだけでも、たとえば50メガバイトのチャンクを大量に割り当てることができます。

アドレス空間の断片化を解決する方法はなく、Bitmapクラスがピクセルデータを格納する方法を修正することはできません。ただし、1つは、プログラムの要件として64ビットバージョンのWindowsを指定することです。それは仮想メモリの塊を提供し、断片化は問題ではありません。それを追跡したい場合は、SysInternalsのVMMapユーティリティを使用してVMレイアウトの洞察を得ることができます。あなたが経験するかもしれない情報過多に注意してください。

于 2012-07-19T10:36:34.493 に答える
0

Windows 64 ビットで作業してみてください。これが、ほとんどのメモリ問題の解決策です。

于 2012-10-31T08:21:12.430 に答える
0

あなたの主な問題は、ビットマップとグラフィックスのインスタンスが同時に多数使用されていることだと思います。

.Dispose() を使用して終了した項目を削除し、一度にできるだけ少ない数になるようにコードを再編成することをお勧めします。

于 2012-07-19T09:39:03.630 に答える