从GIF图像中提取RGB

时间:2013-07-02 19:20:01

标签: c# gif

我需要提取存储在PC(16x16像素)上的小GIF的每个像素的RGB字节值,因为我需要将它们发送到接受RGB 6字节颜色代码的LED显示器。

打开测试文件并将其转换为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 个答案:

答案 0 :(得分: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;
}

使用此方法返回的数据,您可以获得每个像素的RGBA(每个都是单个字节)并执行任何操作你想要他们。

如果您希望最终结果为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(假设您应该如何向其发送图像)。

答案 1 :(得分: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();
}