2013-04-21 38 views
6

Tôi có danh sách pixel ở định dạng nàydữ liệu Pixel Image

ArrayList list = new ArrayList(); 
list.add(Red); 
list.add(Blue); 
list.add(Green); 

Tôi có nhiều giá trị như thế này. Tôi muốn chuyển đổi danh sách mảng thành hình ảnh .. Đã thử rất nhiều nhưng không tìm thấy bất kỳ tài liệu phù hợp nào.

EDIT: này có thể giúp:

List<byte> pic = new List<byte>(); 
for (int j = 0; j < headdata.Count; j++) 
{ 
    if(headdata.ElementAt(j).getHead() == i) 
    { 
     pic.Add((byte)headdata.ElementAt(j).getRed()); 
     pic.Add((byte)headdata.ElementAt(j).getGreen()); 
     pic.Add((byte)headdata.ElementAt(j).getBlue()); 
    } 
} 
+0

Tại sao bạn sử dụng ArrayList để lưu trữ dữ liệu pixel? –

+0

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

+0

Loại dự án của bạn là gì? 'WPF', 'Windows Form', ... –

Trả lời

4

Trước hết, như tôi đã nói trong bình luận, nó sẽ là tốt hơn để sử dụng Danh sách thay vì ArrayList để tránh boxing/unboxing.

Sau đó, bạn cần bpp (bits per pixel) và rộngchiều cao để tạo ra hình ảnh.

nếu bạn có tất cả những giá trị này, sau đó bạn có thể nhận được bắt đầu chỉ số điểm ảnh:

int i = ((y * Width) + x) * (depth/8); 

Ví dụ:

List<byte> bytes = new List<byte>(); // this list should be filled with values 
    int width = 100; 
    int height = 100; 
    int bpp = 24; 

    Bitmap bmp = new Bitmap(width, height); 

    for (int y = 0; y < height; y++) 
    { 
     for (int x = 0; x < width; x++) 
     { 
      int i = ((y * width) + x) * (bpp/8); 
      if(bpp == 24) // in this case you have 3 color values (red, green, blue) 
      { 
       // first byte will be red, because you are writing it as first value 
       byte r = bytes[i]; 
       byte g = bytes[i + 1]; 
       byte b = bytes[i + 2]; 
       Color color = Color.FromArgb(r, g, b); 
       bmp.SetPixel(x, y, color); 
      } 

     } 
    } 

Bạn có thể sử dụng các thư viện khác để tạo bitmap và viết giá trị nhanh hơn. (SetPixel() là rất chậm. See)

+0

Rất hữu ích, Cảm ơn bạn – greatmajestics

8

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.DrawingSystem.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.

+0

Lưu ý: Bạn cần bao gồm 'using System.Runtime.InteropServices;' ở phía trên cùng của tệp để làm việc này. – starbeamrainbowlabs

+0

Oh và bạn cần 'bằng cách sử dụng System.Drawing.Imaging;' quá. – starbeamrainbowlabs

+0

Cảm ơn, đã cập nhật để làm rõ. –

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