2013-07-02 139 views
0

我需要提取存儲在PC(16x16像素)上的小GIF的每個像素的RGB字節值,因爲我需要將它們發送到接受RGB 6字節顏色代碼的LED顯示屏。從GIF圖像中提取RGB

打開測試文件並將其轉換爲1D字節數組後,我得到一些字節值,但我不確定是否解碼GIF幀並因此返回我所需的純192字節RGB數組?

'img = Image.FromFile("mygif.gif");    
    FrameDimension dimension = new FrameDimension(img.FrameDimensionsList[0]); 
    int frameCount = img.GetFrameCount(dimension); 
    img.SelectActiveFrame(dimension, 0); 
    gifarray = imageToByteArray(img);` 

    //image to array conversion func. 
    public byte[] imageToByteArray(System.Drawing.Image imageIn) 
    { 
     MemoryStream ms = new MemoryStream(); 
     imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Gif); 
     return ms.ToArray(); 

    } 

或者也許有另一種方法呢?

回答

2

使用這種方法來獲得包含像素的二維數組:

//using System.Drawing; 
Color[,] getPixels(Image image) 
{ 
    Bitmap bmp = (Bitmap)image; 
    Color[,] pixels = new Color[bmp.Width, bmp.Height]; 

    for (int x = 0; x < bmp.Width; x++) 
     for (int y = 0; y < bmp.Height; y++) 
      pixels[x, y] = bmp.GetPixel(x, y); 

    return pixels; 
} 

使用此方法返回的數據,可以得到每個像素的R,G,BA(每個都是一個字節),然後做任何你想做的事情。

如果你想最終的結果是這樣的byte[]包含值:{ R0, G0, B0, R1, G1, B1, ... },並且像素需要以行優先順序寫入到byte[],那麼你這樣做:

byte[] getImageBytes(Image image) 
{ 
    Bitmap bmp = (Bitmap)image; 
    byte[] bytes = new byte[(bmp.Width * bmp.Height) * 3]; // 3 for R+G+B 

    for (int x = 0; x < bmp.Width; x++) 
    { 
     for (int y = 0; y < bmp.Height; y++) 
     { 
      Color pixel = bmp.GetPixel(x, y); 
      bytes[x + y * bmp.Width + 0] = pixel.R; 
      bytes[x + y * bmp.Width + 1] = pixel.G; 
      bytes[x + y * bmp.Width + 2] = pixel.B; 
     } 
    } 

    return bytes; 
} 

你然後可以將getImageBytes的結果發送到您的LED(假設這就是您應該如何將圖像發送到它)。

+0

謝謝,它的exacly我做什麼,它的工作原理。我只是假設我不能將GIF當作位圖處理。問題是我失去了現在循環幀的選項。 –

+0

好吧,我明白了,它只是從Image類到Bitmap的簡單轉換,並且可以完成。問題已關閉,謝謝您的回覆 –

+0

@PK如果這是正確的答案,那麼請將其標記爲如此。 :) – Jashaszun

1

您的方式不會將其解碼爲原始RGB字節數據。它很可能會輸出與您在開始加載的相同數據(GIF編碼)。

您將需要通過像素提取數據像素:

public byte[] imageToByteArray(Image imageIn) 
{ 
    Bitmap lbBMP = new Bitmap(imageIn); 
    List<byte> lbBytes = new List<byte>(); 

    for(int liY = 0; liY < lbBMP.Height; liY++) 
     for(int liX = 0; liX < lbBMP.Width; liX++) 
     { 
      Color lcCol = lbBMP.GetPixel(liX, liY); 
      lbBytes.AddRange(new[] { lcCol.R, lcCol.G, lcCol.B }); 
     } 

    return lbBytes.ToArray(); 
} 
+0

不要忘記gif可以具有透明度。 Windows編解碼器是否通過Color.A發送? – plinth

+0

是的。由於問題中提到「RGB」而不是「RGBA」,我沒有提及。 – Basuro

+0

好的,它的工作原理。非常感謝,沒有意識到我可以將GIF圖像加載爲位圖。缺點是我可以控制GIF圖像的幀 - 我只能加載第一幀。 –