Search code examples
c#encodingbitmappixelsteganography

setPixel triggering error: InvalidOperationException: 'SetPixel is not supported for images with indexed pixel formats.'


For use in a really basic steganography tool.

I am trying to change the blue value of each pixel to the ASCII value of each character in a message.

Bitmap bmp = new Bitmap(routeBox.Text);
for (int i = 0; i<bmp.Width; i++)
{
    for (int j = 0; j<bmp.Height; j++)
    {
        Color pixelCol = bmp.GetPixel(i, j);
        if (i< 1 && j<textToEmbed.TextLength)
        {
            char letter = Convert.ToChar(textToEmbed.Text.Substring(j, 1));
            int value = Convert.ToInt32(letter);
            bmp.SetPixel(i, j, Color.FromArgb(pixelCol.R, pixelCol.G, value));
        }
    }
}

This works on a jpeg but the blue value comes back as a decrementing number starting around 56 so I'm now trying to do it with a .bmp.

The error is triggered on this line:

bmp.SetPixel(i, j, Color.FromArgb(pixelCol.R, pixelCol.G, value));

To retrieve the message back from the pixels after saving I am doing:

Bitmap bmp = new Bitmap(routeBox.Text);
string message = "";
for (int i = 0; i<bmp.Width; i++)
{
    for (int j = 0; j<bmp.Height; j++)
    {
        Color pixelCol = bmp.GetPixel(i, j);
        if (i< 1 && j< 25)
        {
            int value = pixelCol.B;
            char c = Convert.ToChar(value);
            string letter = System.Text.Encoding.ASCII.GetString(
                new byte[] { Convert.ToByte(c) });
            message = message + letter;
        }
    }
}

Solution

  • The error you’re getting means you can’t call Bitmap.SetPixel() when the image has a PixelFormat of Format8bppIndexed.

    One solution is to use a copy of the image converted to 24-bit instead of 8-bit.

    This means instead of this line:

    Bitmap bmp = new Bitmap(routeBoxText);
    

    Use these 2 lines:

    Bitmap bmpOrig = new Bitmap(routeBoxText);
    Bitmap bmp = bmpOrig.Clone(new Rectangle(0, 0, bmpOrig.Width, bmpOrig.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
    

    For a bit more information about pixel formats and bits-per-pixel, see this page.