4
\$\begingroup\$

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

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)
\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.