从GIF图像中提取RGB

本文关键字:提取 RGB 图像 GIF | 更新日期: 2023-09-27 18:20:42

我需要提取存储在PC上的小GIF(16x16像素)的每个像素的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();
    }

或者可能还有其他方法可以做到这一点?

从GIF图像中提取RGB

使用此方法获取包含像素的2d数组:

//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(假设这就是您应该向其发送图像的方式)。

您的方法不会将其解码为原始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();
}