我有这种格式的列表像素
ArrayList list = new ArrayList();
list.add(Red);
list.add(Blue);
list.add(Green);
我有很多像这样的价值观。我想将数组列表转换为图像..尝试了很多,但没有找到任何合适的材料。
编辑:这可能会有所帮助:
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 :(得分:9)
<强>更新强>
以为我会改进这篇文章以供将来参考。
如果将像素数据存储为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];
/* <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();
您可以创建自己的方法来设置某个坐标的像素:
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;
这种方法通常也很快,如果这对你所做的一切都是必要的 做。
来源:经验。
答案 1 :(得分:5)
首先,正如我在评论中所说,最好使用 List 而不是 ArrayList 来避免装箱/拆箱。
然后,您需要 bpp (每像素位数)和宽度和高度来创建图像。
如果您拥有所有这些值,那么您可以获得起始像素索引:
int i = ((y * Width) + x) * (depth / 8);
例如:
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);
}
}
}
您可以使用其他库来更快地创建位图和写入值。 ( SetPixel()非常慢。See)