C# Displaying 8BPP indexed bitmap in PictureBox causes color issues

46 Views Asked by At

I am having issues displaying 8bpp indexed OpenCV Mat in ImageBox, The image is large size, and I am trying to avoid copying pixel by pixel

The code for the image conversion and display is below But the image comes out in color and not in grayscale, and the color is incorrect. I assume its because its using indexed and not grayscale format in the bitmap. However, there is no option for GrayScale in System.Drawing.Imaging.PixelFormat

Unfortunately I cannot display the image here, Is there any way to fix the issue of displaying 8bpp bitmap on picturebox, or do I need to copy pixel by pixel into each of RGB or RGBA channels

Note, the Mat itself works correctly with ImShow

    unsafe Bitmap ConvertMatToBitmap(Mat matToConvert)
    {
        Bitmap out_bitmap = null;
        if (matToConvert.Width > 0 && matToConvert.Height > 0)
        {
            fixed (byte* p = matToConvert.GetRawData())
            {
                IntPtr ptr = (IntPtr)p;
                if (matToConvert.NumberOfChannels == 1)
                    out_bitmap = new Bitmap(matToConvert.Width,
                    matToConvert.Height, matToConvert.Width,
                    System.Drawing.Imaging.PixelFormat.Format8bppIndexed,
                    ptr);
            }
        }
        return out_bitmap;
    }

And then

    private void PresentCamera(Bitmap out_data)
    {
        imageBox.SizeMode = PictureBoxSizeMode.StretchImage;
        if (out_data != null)
        {
            imageBox.Image = out_data;
        }
    }
1

There are 1 best solutions below

1
Mich On

I needed to define a 1:1 color palette for the indexed image

unsafe Bitmap ConvertMatToBitmap(Mat matToConvert)
{
    Bitmap out_bitmap = null;
    if (matToConvert.Width > 0 && matToConvert.Height > 0)
    {
        fixed (byte* p = matToConvert.GetRawData())
        {
            IntPtr ptr = (IntPtr)p;
            if (matToConvert.NumberOfChannels == 1)
            {
                out_bitmap = new Bitmap(matToConvert.Width,
                matToConvert.Height, matToConvert.Width,
                System.Drawing.Imaging.PixelFormat.Format8bppIndexed,
                ptr);
                    System.Drawing.Imaging.ColorPalette _palette = out_bitmap.Palette;
                    Color[] _entries = _palette.Entries;
                    for (int i = 0; i < 256; i++)
                    {
                        Color b = new Color();
                        b = Color.FromArgb((byte)i, (byte)i, (byte)i);
                        _entries[i] = b;
                    }
                    out_bitmap.Palette = _palette;
              }
        }
    }
    return out_bitmap;
}