3

I know the rgb value of every pixel, and how can I create the picture by these values in C#? I've seen some examples like this:

public Bitmap GetDataPicture(int w, int h, byte[] data)
  {

  Bitmap pic = new Bitmap(this.width, this.height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
  Color c;

  for (int i = 0; i < data.length; i++)
  {
    c = Color.FromArgb(data[i]);
    pic.SetPixel(i%w, i/w, c);
  }

  return pic;
  } 

But it does not works. I have a two-dimensional array like this:

1 3 1 2 4 1 3 ...
2 3 4 2 4 1 3 ...
4 3 1 2 4 1 3 ...
...

Each number correspond to a rgb value, for example, 1 => {244,166,89} 2=>{54,68,125}.

hashtabe_0
  • 127
  • 1
  • 2
  • 11

2 Answers2

3

I'd try the following code, which uses an array of 256 Color entries for the palette (you have to create and fill this in advance):

public Bitmap GetDataPicture(int w, int h, byte[] data)
{
    Bitmap pic = new Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

    for (int x = 0; x < w; x++)
    {
        for (int y = 0; y < h; y++)
        {
            int arrayIndex = y * w + x;
            Color c = Color.FromArgb(
               data[arrayIndex],
               data[arrayIndex + 1],
               data[arrayIndex + 2],
               data[arrayIndex + 3]
            );
            pic.SetPixel(x, y, c);
        }
    }

    return pic;
} 

I tend to iterate over the pixels, not the array, as I find it easier to read the double loop than the single loop and the modulo/division operation.

Thorsten Dittmar
  • 52,871
  • 8
  • 78
  • 129
0

Your solution very near to working code. Just you need the "palette" - i.e. set of 3-elements byte array, where each 3-bytes element contains {R, G, B} values.

    //palette is a 256x3 table
    public static Bitmap GetPictureFromData(int w, int h, byte[] data, byte[][] palette)
    {
      Bitmap pic = new Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
      Color c;

      for (int i = 0; i < data.Length; i++)
      {
          byte[] color_bytes = palette[data[i]];
          c = Color.FromArgb(color_bytes[0], color_bytes[1], color_bytes[2]);
          pic.SetPixel(i % w, i / w, c);
      }

      return pic;
    }

This code works for me, but it very slow.

If you create in-memory "image" of BMP-file and then use Image.FromStream(MemoryStream("image")), it code will be more faster, but it more complex solution.