2011-09-10 42 views
12

Tôi có một vài (~ 2GB) tập tin RGB 24bpp thô trên HDD. Bây giờ tôi muốn lấy một phần của nó và mở rộng nó đến kích thước mong muốn.
(Thang đo duy nhất được phép là 1, 1/2, 1/4, 1/8, ..., 1/256)C# Lấy dữ liệu pixel hiệu quả từ System.Drawing.Bitmap

Vì vậy, tôi hiện đang đọc từng dòng từ hình chữ nhật quan tâm thành một mảng , mà lá tôi với một bitmap có chiều cao chính xác nhưng chiều rộng sai.

Bước tiếp theo tôi tạo Bitmap từ mảng mới được tạo.
Điều này được thực hiện bằng cách sử dụng một con trỏ để không có sao chép dữ liệu liên quan.
Tiếp theo, tôi gọi GetThumbnailImage trên Bitmap, tạo một bitmap mới với kích thước chính xác.

Bây giờ tôi muốn trả về dữ liệu điểm ảnh thô (dưới dạng mảng byte) của bitmap mới được tạo. Nhưng để đạt được điều đó, tôi hiện đang sao chép dữ liệu bằng cách sử dụng LockBits vào một mảng mới.

Vì vậy, câu hỏi của tôi là: Có cách nào để lấy dữ liệu pixel từ Bitmap vào mảng byte mà không sao chép không?

Cái gì như:

var bitmapData = scaledBitmap.LockBits(...) 
byte[] rawBitmapData = (byte[])bitmapData.Scan0.ToPointer() 
scaledBitmap.UnlockBits(bitmapData) 
return rawBitmapData 

Tôi cũng nhận thức rằng điều này không làm việc, nó chỉ là một ví dụ với những gì tôi về cơ bản muốn đạt được.

+0

để hoạt động, Thay vì không an toàn {} void * thành byte [], hãy thử IntPtr ptr = bitmapData.Scan0; int bytes = Math.Abs ​​(bitmapData.Stride) * bitmapData.Height; raw = new byte [bytes]; Marshal.Copy (ptr, raw, 0, bytes); trả về thô; // byte [] – antonio

Trả lời

15

Tôi nghĩ đây là đặt cược tốt nhất của bạn.

var bitmapData = scaledBitmap.LockBits(...); 
var length = bitmapData.Stride * bitmapData.Height; 

byte[] bytes = new byte[length]; 

// Copy bitmap to byte[] 
Marshal.Copy(bitmapData.Scan0, bytes, 0, length); 
scaledBitmap.UnlockBits(bitmapData); 

Bạn phải sao chép nó, nếu bạn muốn vượt qua một byte [].

Bạn không phải xóa các byte đã được cấp phát, bạn chỉ cần Vứt bỏ đối tượng Bitmap gốc khi thực hiện khi nó triển khai IDisposable.

+0

Không chính xác câu trả lời tôi đã hy vọng, nhưng bằng cách sử dụng Marshal.Copy làm cho nó trông đẹp hơn rất nhiều so với sao chép nó số nguyên trên mỗi số nguyên. Cảm ơn – Arokh

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