Skip to main content

 none
Grayscale 8bits image RRS feed

  • Question

  • Hello,

    I have to generate a JPG Grayscale 8bits image with "color space" = grayscale.

    The code below generates a color space = "Indexed Color (256 colors)".

    What should i do to generate a grayscale color space image using GDI?

    public static Bitmap Grayscale8bpp(Bitmap original)
            {
                //create a blank bitmap the same size as original
                Bitmap newBitmap = new Bitmap(original.Width, original.Height)
                {
                    Palette = GetGrayScalePalette()
                };

                //get a graphics object from the new image
                Graphics g = Graphics.FromImage(newBitmap);

                //create the grayscale ColorMatrix
                ColorMatrix colorMatrix = new ColorMatrix(
                   new float[][]
                   {
                     new float[] {.3f, .3f, .3f, 0, 0},
                     new float[] {.59f, .59f, .59f, 0, 0},
                     new float[] {.11f, .11f, .11f, 0, 0},
                     new float[] {0, 0, 0, 1, 0},
                     new float[] {0, 0, 0, 0, 1}
                   });

                //create some image attributes
                ImageAttributes attributes = new ImageAttributes();

                //set the color matrix attribute
                attributes.SetColorMatrix(colorMatrix);


                //draw the original image on the new image
                //using the grayscale color matrix
                g.DrawImage(original, new Rectangle(0, 0, original.Width, original.Height),
                   0, 0, original.Width, original.Height, GraphicsUnit.Pixel, attributes);

                //dispose the Graphics object
                g.Dispose();

                return newBitmap.Clone(new Rectangle(0, 0, newBitmap.Width, newBitmap.Height), PixelFormat.Format8bppIndexed);  
            }

            public static ColorPalette GetGrayScalePalette()
            {
                using (var bmp = new Bitmap(1, 1, PixelFormat.Format8bppIndexed))
                {
                    var cp = bmp.Palette;
                    var entries = cp.Entries;
                    for (int i = 0; i < entries.Length; i++)
                    {
                        entries[i] = Color.FromArgb(i, i, i);
                    }
                    return cp;
                }
            }

    Tuesday, April 10, 2018 2:13 PM

All replies

  • None of this generates a JPEG.  This is all just in memory.  When stored in memory, a grayscale image is just an 8-bit indexed image, as you have created here.  Where do you create the JPEG?

    Tim Roberts, Driver MVP Providenza & Boekelheide, Inc.

    Tuesday, April 10, 2018 5:43 PM
  • Hi,

    Thank you for posting here.

    If you want to generate the JPEG format picture, did you try to use the libjpeg library?

    Libjpeg is a widely used C library for reading and writing JPEG image files. It was developed by Tom Lane and the Independent JPEG Group (IJG) during the 1990's and it is now maintained by several developers using various services identified in the SourceForge summary. 
    This is a stable and solid foundation for many application's JPEG support.

    Best Regards,

    Hart


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, April 11, 2018 8:55 AM
    Moderator
  • Hello Tim!

    I´m using the following code to save the bitmap:

    var bmp = Grayscale8bpp(source);

    bmp.Save(@"C:\temp\test.jpg", ImageFormat.Jpeg);

    Wednesday, April 11, 2018 12:10 PM
  • Hello Hart!

    I will look for a wrapper in .net for libjpeg.

    Is this a limitation of GDI?

    Wednesday, April 11, 2018 12:13 PM
  • @marcelohao,

    What do you mean by saying limitation?

    Best regards,

    Barry


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, April 19, 2018 8:32 AM
  • Your code appears to convert the input image to grayscale, but when you save, the Bitmap class saves it as 24-bit image, not 8-bit.

    GDI does not support saving real 8-bit JPEG images, but one way to do that is to do the conversion using a professional imaging SDK that support this image format like the LEADTOOLS toolkit (https://www.leadtools.com/sdk/formats).

    (Disclaimer: I am an employee of the vendor of this toolkit).

    The code for doing the conversion would look like this:
    RasterCodecs codecs = new RasterCodecs();
    RasterImage DestingationImage = codecs.Load(SourceImagePath);
    //Note: When saving 8-bit JPEG, it’s always grayscale, so the conversion to gray colors is automatic
    codecs.Save(DestingationImage, @"C:\temp\test.jpg", RasterImageFormat.Jpeg411, 8);
    Thursday, May 31, 2018 4:00 PM