# Convert an image to 8-bit color

I have a function that will take an image and then return that image in 8-bit color. Almost all of the code was taken from MSDN.

The code is quite short compared to all of the other methods I've seen for converting an image to 8-bit color. I'm just curious as to if this is the most efficient method?

private static Image ImageTo8bpp(Image image)
{
var bitmap = new Bitmap(image);
var imageCodecInfo = GetEncoderInfo("image/tiff");
var encoder = Encoder.ColorDepth;
var encoderParameters = new EncoderParameters(1);
var encoderParameter = new EncoderParameter(encoder, 8L);
encoderParameters.Param[0] = encoderParameter;
var memoryStream = new MemoryStream();
bitmap.Save(memoryStream, imageCodecInfo, encoderParameters);
return Image.FromStream(memoryStream);
}

private static ImageCodecInfo GetEncoderInfo(string mimeType)
{
var imageEncoders = ImageCodecInfo.GetImageEncoders();
return imageEncoders.FirstOrDefault(t => t.MimeType == mimeType);
}

• Looking at the MSDN link in question, seems the code was more derived or inspired by than taken, no? – Mathieu Guindon Sep 2 '16 at 15:40
• @Mat'sMug I cleaned it up, removed all the comments, and made it save to a MemoryStream instead. – Owen Sep 2 '16 at 15:48
• I have rolled back the last edit. Please see what you may and may not do after receiving answers. – Mathieu Guindon Sep 2 '16 at 18:30
• @Mat'sMug I was not aware of that rule. I'm sorry! :I – Owen Sep 2 '16 at 18:32

The MSDN example is saving to a physical file, so the method incurs I/O - yours streams it to a MemoryStream, so it definitely feels more efficient.

I'm a bit (pun not intended) worried about the undisposed Bitmap and MemoryStream objects though, both of which implement the IDisposable interface, and I think some of the intermediate variables could be skipped - would this work?

using (var bitmap = new Bitmap(image))
using (var stream = new MemoryStream())
{
var parameters = new EncoderParameters(1);
parameters.Param[0] = new EncoderParameter(Encoder.ColorDepth, 8L);

var info = GetEncoderInfo("image/tiff");
bitmap.Save(stream, info, parameters);

return Image.FromStream(stream);
}


I'd be almost tempted to inline GetEncoderInfo too, unless it's reused elsewhere.

That would take this line:

    var info = GetEncoderInfo("image/tiff");


And turn it into...

    var info = ImageCodecInfo.GetImageEncoders()
.FirstOrDefault(info => info.MimeType == "image/tiff");


If the method is used in a number of places (hmm, well it's private so I doubt it), it could be interesting to turn the method (which is already static anyway) into an extension method:

public static Image To8bit(this Image image)