save jpg with lower bit depth (24 to 16 for instance) (C#)

10,113

Solution 1

JPEG is a three-color format. It usually has 8 bits per color, but can have 12 or 16. 24=3x8 bits of color is therefore reasonable, but 16 or 32 is simply impossible. It just doesn't divide by three. 3x16=48 would be possible, but that's a higher color depth. JPEG is designed for photo's, and it doesn't make sense to support lower bit depths than 3x8. There's no benefit in that.

Now, what is the 16 bit image in your code? It's an imprecise in-memory approximation of the original, using only 65535 colors. When you save that back, you get a 24 bits JPEG. Apparently your JPEG encoder doesn't know how to create an 48 bits JPEG. Even if it did, it would be a waste of bits since the in-memory image only has 65536 colors anyway.

To summarize: what is going wrong is the task. There's no such thing as a 65536 color JPEG.

Solution 2

JPEG is a three colors format and it does not allow you to save as 16 bit depth but bmp format does. I encountered the same problem and I solved it as below. Hope it will help you.

bmp.Save("test.jpeg", ImageFormat.Bmp);

Solution 3

This question is a bit old, but I will add this for anyone searching in the future.

If it is a 32 bit file, then most likely it is in the CMYK colorspace. This is typically used for printing, but its rare enough that many tools that use RGB and display to screens rather than print can't handle it.

You can convert it to RGB using imagemagic:

convert imageInCMYK.jpg -colorspace RGB imageInRGB.jpg
Share:
10,113
Frank
Author by

Frank

Author of "Getting started with Java on the Raspberry Pi" https://leanpub.com/gettingstartedwithjavaontheraspberrypi/ Software developer at Toadi (Belgium) Lead Coach at CoderDojo Belgium Ieper Particularly interested in client/server and relational database design using MSSQL/MySql Server, digital signage, user experience,... Specialized in integration of different systems in one easy-to-use system. XML, HTML, JavaScript, usability, CSS, C#, Java, Python, Flex, Actionscript, ERP Solutions, Multimedia authoring, ...

Updated on June 17, 2022

Comments

  • Frank
    Frank almost 2 years

    I need to convert 24- and 32-bits jpeg and png-files to a lower bit depth (16). I found some code to do this, but the resulting images keep the bit depth of the original file although there file size is lower.

    Image img = Image.FromFile(filePathOriginal);
    Bitmap bmp = ConvertTo16bpp(img);
    EncoderParameters parameters = new EncoderParameters();
    parameters.Param[0] = new EncoderParameter(Encoder.ColorDepth, 16);
    bmp.Save(filePathNew, jpgCodec, parameters);
    bmp.Dispose();
    img.Dispose();
    
    ...
    
    private static Bitmap ConvertTo16bpp(Image img) {
        var bmp = new Bitmap(img.Width, img.Height, System.Drawing.Imaging.PixelFormat.Format16bppRgb555);
        using (var gr = Graphics.FromImage(bmp))
        {
             gr.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height));
        }
    
        return bmp;
    }
    

    Any ideas what's going wrong?

    Thanks, Frank

  • Frank
    Frank over 13 years
    thanks msalters. I can follow the logic of your answer. If I compare the original and converted image, they have both 24 bit depth, but the filesize is reduced with a test image from 2218 kb to 959 kb. When I compare the image quality, there is not much difference, only the converted one is a little bit darker.
  • Frank
    Frank over 13 years
    other difference: with png, the transparancy is lost
  • MSalters
    MSalters over 13 years
    @Frank: No wonder on the PNG side, the in-memory reduction to a 65536 color bitmap strips out the alpha channel. You can't get that back either. As for the reduction in JPEG size, it's to be expected. The reduction to 65536 colors will eliminate small color differences, that would otherwise need to be encoded. However, JPEG compression has a "quality" factor. Compression at a lower quality will also eliminate small details, but will preferentially eliminate details for which the human eye is less sensitive. That's probably a better alternative for your problem.