2013-04-21 46 views
6

我名单像素的图形格式像素数据,图像

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

为什么你使用ArrayList存储像素数据? – 2013-04-21 10:36:17

+0

我正在聚集图像,所以我不知道从开始的图像集群的确切大小,如果我在大型数据集上运行一次循环,它需要很多时间..所以我使用数组列表进行动态分配 – greatmajestics 2013-04-21 10:37:13

+0

什么是您的项目类型? 'WPF','Windows Form',... – 2013-04-21 10:39:46

回答

4

首先,正如我在评论说,这将是更好地使用名单而不是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

+0

非常有帮助,谢谢 – greatmajestics 2013-04-21 11:07:53

8

更新

以为我会改进这个帖子以供将来参考。

如果将像素数据存储为32位整数(理想情况下无符号数组),则更容易。每个整数的4个字节应分别对应于alpha,红色,绿色和蓝色通道。如果您不使用Alpha通道,请将其保持为空。

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

由于starbeamrainbowlabs指出:

GCHandleBitmap,并PixelFormatSystem.Runtime.InteropServices发现,System.Drawing

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

您可以在某个坐标设定像素创建你自己的方法,和System.Drawing.Imaging

原来的答案下面

有这样做的相当的好方法,但它需要你使用数组或字节,而不是一个列表。如果你想改变这是ARGB,只需更改的 '3' 所有实例 '4', 和使用PixelFormat.Format32bppArgb

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

考虑这一点。

正如我所说的,这需要你使用一个数组而不是一个列表,但这个 应该不会太困难,只要你知道图像的宽度和高度。 数组中设置一个单独的像素(也许会让一个方法 本)的一个好办法:

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

这种方法一般是相当快过,如果这是在所有必要的不管你是 做。

来源:经验。

+0

注意:您需要在文件顶部包含'using System.Runtime.InteropServices;'才能使其工作。 – starbeamrainbowlabs 2015-08-29 19:15:14

+0

哦,你也需要'使用System.Drawing.Imaging;'。 – starbeamrainbowlabs 2015-08-29 19:20:42

+0

谢谢,更新澄清。 – 2015-08-29 19:45:43

相关问题