2012-03-24 21 views
5

Tôi cần hiển thị bitmap 1027 * 768 tới cửa sổ ứng dụng (cùng kích thước) và không có nhiều hơn 10-15 ms để hoàn thành tác vụ này. Tôi đang sử dụng bufferedGraphics được cấp phát từ một đối tượng đệm bufferedGraphicsContect và vẫn nhận thấy các vấn đề hiệu suất rất lớn.Viết cho bề mặt đồ họa đệm qua con trỏ manupilation

Tôi đang sử dụng mã không an toàn để thực hiện hoạt động sao chép của tôitìm thấy kết quả không thể tin được. Tôi biết các đối tượng đồ họa/BufferedGraphics nên có một số loại bề mặt vẽ trong bộ nhớ. Tôi đã tự hỏi nếu ai đó có thể chỉ cho tôi đi đúng hướng về cách viết lên bề mặt này bằng cách sử dụng Marshal hoặc một số phương pháp cấp thấp không an toàn khác.

Tôi đang trong quá trình chuyển một ứng dụng đồ họa C# cũ hơn. Tôi biết C# không được thiết kế cho đồ họa nặng và có những công cụ tốt hơn GDI +, tiếc là tôi không có những thứ xa xỉ đó.

Đây là những gì tôi đã đưa ra cho đến nay ... Bất kỳ cái nhìn sâu sắc những gì như vậy bao giờ là rất nhiều apperciated.

byte[] _argbs = null; 
static readonly Bitmap _bmUnderlay = Properties.Resources.bg; 
static Bitmap _bmpRender = new Bitmap(1024, 768, System.Drawing.Imaging.PixelFormat.Format24bppRgb); 
int bmpHeight = Properties.Resources.bg.Height; 
int bmpWidth = Properties.Resources.bg.Width; 
static BufferedGraphicsContext _bgc = new BufferedGraphicsContext(); 

internal unsafe void FillBackBuffer(Point cameraPos) 
{ 
     // lock up the parts of the original image to read (parts of it) 
     System.Drawing.Imaging.BitmapData bmd = _bmUnderlay.LockBits(
      new Rectangle(cameraPos.X, cameraPos.Y, 1024, 768), 
      System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb); 
     // get the address of the first line. 
     IntPtr ptr = bmd.Scan0; 

     //if (_argbs == null || _argbs.Length != bmd.Stride * bmd.Height) 
     // _argbs = new byte[bmd.Stride * bmd.Height]; 
     if (_argbs == null || _argbs.Length != 1024 * 3 * 768) 
      _argbs = new byte[1024 * 3 * 768]; 

     // copy data out to a buffer 
     Marshal.Copy(ptr, _argbs, 0, 1024 * 3 * 768); 

     _bmUnderlay.UnlockBits(bmd); 

     // lock the new image to write to (all of it) 
     System.Drawing.Imaging.BitmapData bmdNew = _bmpRender.LockBits(
      new Rectangle(0, 0, 1024, 768), 
      System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb); 
     // copy data to new bitmap 
     Marshal.Copy(_argbs, 0, bmdNew.Scan0, 1024 * 3 * 768); 
     _bmpRender.UnlockBits(bmdNew); 
} 

private unsafe void _btnGo_Click(object sender, EventArgs e) 
{ 
    // less than 2 ms to complete!!!!!!!! 
    FillBackBuffer(new Point()); 

    using (BufferedGraphics bg = _bgc.Allocate(CreateGraphics(), ClientRectangle)) 
    { 
     System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); 
     sw.Start(); 
     ///// 
     /// 
     // This method takes over 17 ms to complete 
     bg.Graphics.DrawImageUnscaled(_bmpRender, new Point()); 
     // 
     /// 
     ///// 
     sw.Start(); 
     this.Text = sw.Elapsed.TotalMilliseconds.ToString(); 

     bg.Render(); 
    } 
} 

EDIT:

Quên đề cập đến Tôi đang tìm kiếm một mức độ thay thế thấp để Graphics.DrawImage(), tốt hơn bằng văn bản cho bộ nhớ bề mặt đồ họa, sử dụng con trỏ? Cảm ơn bạn lần nữa

+0

tôi chỉnh sửa thụt đầu dòng mã và nó dường như có một cú đúp xoăn danging ở cuối. Nếu đây là một vấn đề về kết thúc của tôi, xin vui lòng quay trở lại chỉnh sửa của tôi – puk

+0

Thanks for the help, tôi nghĩ rằng cú đúp là một phần của trục vít của tôi lên là tốt, xin lỗi :) – OverMars

Trả lời

3

Chú ý đến định dạng pixel của bitmap. Trên phần cứng video 32bpp chuẩn, Format32bppPArgb hiển thị nhanh gấp mười lần so với bất kỳ phần cứng nào khác. Bởi vì các pixel không cần bất kỳ bản dịch nào. Định dạng 24bpp bạn sử dụng bây giờ cần phải được mở rộng đến 32bpp và không đến miễn phí. Đừng bỏ qua P của PArgb và đừng quên đặt giá trị alpha là 255 trong mã của bạn.

Sử dụng BufferedGraphics là cá btw. Bạn nên luôn luôn sử dụng một trong những bạn nhận được miễn phí trong phương pháp OnPaint. Và có lẽ bạn không cần một cái gì cả vì bạn đang đập nhanh. Đó là tốc độ 2x tự động.

+0

Điều đó đã giúp nhiều hơn tôi mong đợi, nhờ tôi sử dụng bufferedGraphics vì sau khi điền vào cửa sổ máy khách, tôi thêm một số lớp bitmap khác! :(C# là sooo không có nghĩa là cho này ... – OverMars

+0

Hmm, không có bất cứ điều gì để làm với ngôn ngữ. Bạn chỉ cần sử dụng một ít hơn thư viện đồ họa lý tưởng. GDI + là rất phù hợp nhưng nếu bạn muốn Perf sau đó bạn cần một thư viện quản lý video DirectX bộ nhớ. Ví dụ, SlimDX có một wrapper quản lý cho nó. –

Các vấn đề liên quan