2013-04-21 44 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

相關問題