像素数据到图像

我有这种格式的列表像素

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

我有很多像这样的价值观。 我想将数组列表转换为图像..尝试了很多,但没有找到任何适当的材料。

编辑:这可能有助于:

 List pic = new List(); 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()); } } 

首先,正如我在评论中所说,最好使用List而不是ArrayList来避免装箱/拆箱。

然后,您需要bpp (每像素位数)和宽度高度来创建图像。

如果你有所有这些值,那么你可以得到起始像素索引:

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

例如:

  List bytes = new List(); // 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); } } } 

您可以使用其他库来更快地创建位图和写入值。 ( SetPixel()非常慢。 请参阅 )

更新

以为我会改进这篇文章以供将来参考。

如果将像素数据存储为32位整数数组(理想情况下为无符号),则要容易得多。 每个整数的4个字节应分别对应于alpha,red,green和blue通道。 如果您没有使用Alpha通道,请将其保持为空。

 // 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]; /*  */ // 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()); /*  */ // Free the handle to stop the GC from pinning the array. // This is important if you were dealing with a large array. gchPixels.Free(); 

您可以创建自己的方法来设置某个坐标的像素:

 public void SetPixel(int x, int y, uint colour) => pixels[x + y * width] = colour; 

正如starbeamrainbowlabs指出:

GCHandleBitmapPixelFormat分别位于System.Runtime.InteropServicesSystem.DrawingSystem.Drawing.Imaging

原文如下

有很好的方法可以做到这一点,但它需要使用数组或字节而不是列表。

考虑一下:

 // 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()); 

如果要将其更改为ARGB,只需使用“4”更改“3”的所有实例,并使用PixelFormat.Format32bppArgb。

正如我所说,这要求您使用数组而不是列表,但只要您知道图像的宽度和高度,这就不会太困难。 在数组中设置单个像素的好方法是(也许为此设置方法):

 pixels[x + y * width] = R; pixels[x + y * width + 1] = G; pixels[x + y * width + 2] = B; 

这种方法通常也很快,如果这对你所做的一切都是必要的。

资料来源:经验。