views:

513

answers:

4

bpp = bits per pixel, so 32bpp means 8/8/8/8 for R/G/B/A.

Like .NET has an enum for these "System.Drawing.Imaging.PixelFormat".

Now once I have a Bitmap or Image object with my graphics, how would I save it to a file / what format would I use?

What image file format (JPEG/GIF/PNG) supports low bit-depths like 16bpp or 8bpp (instead of the usual 32bpp or 24bpp)

A: 

Untested code -

Image myImage = new Image();
EncoderParameters parameters = new EncoderParameters(1);   
parameters.Param[0] = new EncoderParameter(Encoder.ColorDepth, 8);
myImage.Save(somestream, ImageFormat.Png, parameters);

Look at the System.Drawing.Imaging namespace and have a play with the Encoder.xxx parameter settings and the image.Save method. HTH.

Update also worth noting that if you want a small image (low byte count) you can try saving as JPEG an using Encoder.Compression compression but at image quality cost.

Dead account
+1  A: 

Try this:

ImageCodecInfo pngCodec = ImageCodecInfo.GetImageEncoders().Where(codec => codec.FormatID.Equals(ImageFormat.Png.Guid)).FirstOrDefault();
if (pngCodec != null)
{
    EncoderParameters parameters = new EncoderParameters();
    parameters.Param[0] = new EncoderParameter(Encoder.ColorDepth, 8);
    myImage.Save(myStream, pngCodec, parameters);
}
Vojislav Stojkovic
+1  A: 

All image formats effectively support low bit depths. You just leave the last bits unused, if not needed. GIF only supports low-color; you're restricted to 256 colors.

MSalters
+1  A: 

I don't think the other's answering tested their code as GDI+ PNG does not support the Encoder.BitDepth EncoderParameter. In fact, the only Codec which does is TIFF.

You need to change your image's PixelFormat before saving in order to have any effect out the output. This won't always produce the PixelFormat you expect. See my post here for more information on which PixelFormats turn into what.

As for PixelFormat conversions, something like the following will work:

private Bitmap ChangePixelFormat(Bitmap inputImage, PixelFormat newFormat)
{
  Bitmap bmp = new Bitmap(inputImage.Width, inputImage.Height, newFormat);
  using (Graphics g = Graphics.FromImage(bmp))
  {
    g.DrawImage(inputImage, 0, 0);
  }
  return bmp;
}

Unfortunately, these conversions can produce some really bad output. This is especially true in the case where you are performing a lossy conversion (high bit depth to lower).

Rick Minerich