2012-07-19 7 views
5

Tôi mới sử dụng C#. Vì vậy, tôi không chắc chắn vấn đề là gì với chương trình của tôi. Chương trình hoạt động với hình ảnh nhỏ nhưng nó cho thấy "Out of memory exeception" khi nó hoạt động với một hình ảnh lớn có kích thước A4. Tuy nhiên, chương trình sẽ vô ích nếu nó không thể hoạt động với hình ảnh lớn. Tôi có thể giải quyết vấn đề bằng cách nào? Với cảm ơn.Hết bộ nhớ ngoại lệ trong 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

Không liên quan đến việc trả lời câu hỏi của bạn, bạn phải lưu ý rằng bạn phải đóng và xử lý các đối tượng đồ họa của mình. Các đoạn mã pad với các câu lệnh 'using'. Điều đó sẽ làm công việc. –

+5

Kích thước A4 không nói bất cứ điều gì. Tôi có thể tạo ra một hình ảnh kích thước A4 chỉ với 4 pixel trong nó :) –

+0

Không chắc chắn vấn đề là gì, nhưng cố gắng thêm bằng cách sử dụng các câu lệnh xung quanh mọi đối tượng thực hiện IDisposable (Bitmap, Graphics). Bao nhiêu bộ nhớ là quá trình sử dụng khi bạn nhìn vào trình quản lý tác vụ? – Maarten

Trả lời

0

Tôi nghi ngờ rằng vấn đề chính của bạn là bạn đã có một số trường hợp bitmap và đồ họa được sử dụng cùng một lúc.

Có thể bạn đang cố gắng sắp xếp lại mã của mình để có thể sử dụng ít nhất một lần trong số đó, sử dụng .Dispose() để xóa các mục bạn đã hoàn thành.

8

nó là một hình ảnh 9992x8750

Vâng, bạn đang ở trong khu vực nguy hiểm cho một quá trình 32-bit. Hình ảnh đó yêu cầu một không gian địa chỉ tiếp giáp lớn, 334 megabyte. Bạn sẽ dễ dàng nhận được điều đó khi bạn tải hình ảnh sớm, ngay sau khi chương trình của bạn bắt đầu. Bạn có thể nhận được khoảng 650 megabyte tại thời điểm đó, cho hay lấy.

Nhưng điều đó đi xuống đồi từ đó khi chương trình của bạn phân bổ và giải phóng bộ nhớ và tải một vài hội đồng. Không gian địa chỉ bị phân mảnh, các lỗ hổng giữa các phân bổ ngày càng nhỏ hơn. Chỉ cần tải một DLL với một địa chỉ cơ sở khó xử có thể đột nhiên cắt lỗ lớn nhất bởi hơn một yếu tố của hai. Vấn đề không phải là tổng số lượng bộ nhớ ảo có sẵn, nó có thể là một gigabyte hoặc nhiều hơn, nó là kích thước của phần lớn nhất có sẵn. Sau một thời gian, việc phân bổ 90 megabyte không hoàn toàn không bình thường. Chỉ cần một phân bổ mới có thể không thành công, bạn vẫn có thể phân bổ một nhóm gồm 50 megabyte.

Không có cách nào để phân mảnh không gian địa chỉ và bạn không thể sửa chữa cách lớp Bitmap lưu trữ dữ liệu pixel. Nhưng một, chỉ định một phiên bản 64-bit của Windows như một yêu cầu cho chương trình của bạn. Nó cung cấp gobs của bộ nhớ ảo, phân mảnh là một vấn đề không. Nếu bạn muốn đuổi nó xuống thì bạn có thể có được cái nhìn sâu sắc trong cách bố trí VM với SysInternals 'VMMap utility. Cẩn thận với quá tải thông tin bạn có thể gặp phải.

0

Hãy thử làm việc trên Windows 64 bit, Đó là giải pháp của hầu hết các vấn đề về bộ nhớ.