像素数据到图像
我有这种格式的列表像素
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指出:
GCHandle
, Bitmap
和PixelFormat
分别位于System.Runtime.InteropServices
, System.Drawing
和System.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;
这种方法通常也很快,如果这对你所做的一切都是必要的。
资料来源:经验。