Search code examples
c#imageopencvbitmapgrayscale

Convert Image 16bits grayscale to Bitmap 16bits grayscale (Constructor error)


I try to convert a Image (16bits grayscale) to Bitmap (16bits grayscale).

This example doesn't works (Exception : ArgumentException)

    private Mat ToMat16bGrayscale(Image im)
    {

        Bitmap bmp2 = new Bitmap(im); 

    }

But this example works :

 private Mat ToMat16bGrayscale(Image im)
 {

   //Cast obligatoire la création ou la copie d'une bitmap ne   fonctionne pas ici... 
                Bitmap bmp = (Bitmap)(im);
                Bitmap new_bmp = (Bitmap)bmp.Clone(); 
 }

I want to know why the constructor Bitmap doesn't works with a Image 16bits grayscale and why the cast Image to Bitmap works.

Thanks :)


Solution

  • PixelFormat.Format16bppGrayscale is a white elephant image format. Commodity hardware, the kind you'd find back in your machine, isn't even remotely close to being able to accurately render such a bitmap. Which is RGB-based with 8 bits for each color channel, producing 16 million distinct colors. Only 256 of them are shades of gray. Even worse are commodity LCD monitors, they generally can't do better than make 6 bits of color info distinctive, in effect rendering no more than 64 shades of gray. Mapping 65,536 shades of gray down to 256 or 64 of course causes lots of details to be lost.

    It does get used in very specialized applications. One is radiological imaging, displaying X-ray images for example. But they also have extraordinary expensive monitors to display such an image. The non-trivial electrical component is the D/A converter, a 16-bit converter that can run at ~250 MHz costs lots and lots of money. They also use specialized image file formats, DICOM is common, formats that are not otherwise supported by the codecs included with GDI+.

    There is significant liability here, always an issue in the USA, when you display such a medical image on commodity hardware then whomever looks at it isn't going to be able to see enough details to properly diagnose, say, an evolving tumor. In itself enough to discourage Microsoft to support pixel format conversions for the pixel format, they do not want to be involved in such a lawsuit.

    GDI+ supports storing such an image. You can get to the pixel data with Bitmap.LockBits(). Suitable enough for image processing applications. But any attempt to create a Graphics object for such an image or using Graphics.DrawImage() on such an image will cause an exception. Which is what the Bitmap(Image) constructor does. Look for a vendor like LeadTools for library support.