HiveBrain v1.2.0
Get Started
← Back to all entries
snippetcsharpMinor

Convert an image to 8-bit color

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
convertbitimagecolor

Problem

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);
}

Solution

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)

Code Snippets

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);
}
var info = GetEncoderInfo("image/tiff");
var info = ImageCodecInfo.GetImageEncoders()
                             .FirstOrDefault(info => info.MimeType == "image/tiff");
public static Image To8bit(this Image image)

Context

StackExchange Code Review Q#140323, answer score: 6

Revisions (0)

No revisions yet.