Cập nhật
nghĩ rằng tôi muốn cải thiện bài này để tham khảo trong tương lai.
Sẽ dễ dàng hơn nếu bạn lưu trữ dữ liệu pixel dưới dạng mảng số nguyên 32 bit (lý tưởng chưa được ký). 4 byte của mỗi số nguyên phải tương ứng với các kênh alpha, red, green và blue tương ứng. Nếu bạn không sử dụng kênh alpha, chỉ cần giữ nó ở chế độ trống.
// If your image is always going to be the same size, make these constant -
// it speeds things up tremendously.
var width = 640;
var height = 480;
// Create the array to contain bitmap's pixel data.
// Making the pixels unsigned *can* speed up certain arithmetic operations,
// so use them if you're going to be manipulating colours as integers in the array.
// Note that array size is width * height only.
var pixels = new uint[width * height];
/* <Perform array operations here> */
// Create a handle to the object on the heap.
// Making it 'Pinned' prevents the GC from moving it around in memory.
var gchPixels = GCHandle.Alloc(pixels, GCHandleType.Pinned);
// Create the bitmap itself.
// Note: if you plan on making use of the alpha channel, make sure you use
// Format32bppArgb instead (no P).
// Format32bppPArgb means that the alpha channel is present but should be ignored.
var bitmap = new Bitmap(width, height, width * sizeof(uint),
PixelFormat.Format32bppPArgb,
gchPixels.AddrOfPinnedObject());
/* <Perform bitmap operations here> */
// Free the handle to stop the GC from pinning the array.
// This is important if you were dealing with a large array.
gchPixels.Free();
Bạn có thể tạo phương pháp riêng của mình để thiết lập một điểm ảnh một lúc nào đó phối hợp:
public void SetPixel(int x, int y, uint colour) => pixels[x + y * width] = colour;
Như starbeamrainbowlabs chỉ ra:
GCHandle
, Bitmap
, và PixelFormat
được tìm thấy trong System.Runtime.InteropServices
, System.Drawing
và System.Drawing.Imaging
tương ứng.
gốc trả lời Dưới
Có một cách khá tốt để làm điều này, nhưng nó đòi hỏi bạn phải sử dụng một mảng hoặc byte như trái ngược với một danh sách.
Hãy xem xét điều này:
// Define the width and the height of the image
int width = 100,
height = 100;
/* Create an array of bytes consisting of the area's worth of pixels
* with 3 bytes of data each.
*/
byte[] pixels = new byte[width * height * 3];
/* > Code for making the image etc. here < */
// Create our bitmap.
/* GCHandle requires System.Runtime.InteropServices
* PixelFormat requires System.Drawing.Imaging.
*/
Bitmap bmp = new Bitmap(width, height, width * 3, PixelFormat.Format24bppRgb,
GCHandle.Alloc(pixels, GCHandleType.Pinned).AddrOfPinnedObject());
Nếu bạn muốn thay đổi điều này là ARGB, chỉ đơn giản là thay đổi tất cả các trường hợp của '3' với '4', và sử dụng PixelFormat.Format32bppArgb.
Như tôi đã nói, điều này yêu cầu bạn sử dụng một mảng trái ngược với danh sách, nhưng điều này không nên quá khó khăn miễn là bạn biết chiều rộng và chiều cao của hình ảnh. Một cách tốt để thiết lập một điểm ảnh riêng biệt trong mảng được (có lẽ làm cho một phương pháp cho việc này):
pixels[x + y * width] = R;
pixels[x + y * width + 1] = G;
pixels[x + y * width + 2] = B;
Phương pháp này nói chung là khá nhanh quá, nếu đó là ở tất cả cần thiết cho bất cứ điều gì bạn đang làm .
Nguồn: trải nghiệm.
Tại sao bạn sử dụng ArrayList để lưu trữ dữ liệu pixel? –
Tôi sắp xếp hình ảnh, vì vậy tôi không biết kích thước chính xác của cụm hình ảnh từ đầu, nếu tôi chạy vòng lặp một lần trên bộ dữ liệu lớn cần nhiều thời gian .. vì vậy tôi đang sử dụng arraylist để phân bổ động – greatmajestics
Loại dự án của bạn là gì? 'WPF', 'Windows Form', ... –