Getting System.Drawing.Imaging.ImageFormat from a string

Get ImageFormat based on file extension using Reflection

  • Share

Images are part of pretty much any application especially web. Not so rarely they need to be protected or exposed from a different sources which cannot be accessed directly with just typing URL to it's actual location.

It all comes down to writing image bytes to an output stream. This pretty easy to do in C# and ASP.NET. The following snippet instantiates a bitmap from a physical path, writes it to a MemoryStream and then to a response content as an array of bytes.

MemoryStream ms = new MemoryStream();
            HttpContext context = HttpContext.Current;
            string filePath = context.Server.MapPath(filename);

            new Bitmap(filePath).Save(ms, ImageFormat.Png);

            HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
            result.Content = new ByteArrayContent(ms.ToArray());
    

It's all fine except one small thing. Format of the image used to write it to MemoryStream is hardcoded to ImageFormat.Png.

Ideally it would depend on file extension for example. The problem is that ImageFormat is not an enumeration. It is sealed static class with static fields for each image format and there is no method for getting image format for a string value. The easy way is to write a long switch/case condition for known image format file extensions.

It's not so hard to do this but there is a lot of typing, so I decided to give it a try with reflection, so I came up with the following method.

        public static ImageFormat GetImageFormat(string extension)
        {
            ImageFormat result = null;
            PropertyInfo prop = typeof(ImageFormat).GetProperties().Where(p => p.Name.Equals(extension, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
            if (prop != null)
            {
                result = prop.GetValue(prop) as ImageFormat;
            }
            return result;
        }
    

The only bad thing about this method is that it cannot be written as an extension for ImageFormat class since ImageFormat class is static class and extension method requires an instance to be applied :(

Since file can have extension which is not one of the ImageFormat values, it is not bad to write a fallback with an inline condition, just in case something like this happens. I decided to return ImageFormat.Bmp for the fallback option

MemoryStream ms = new MemoryStream();
            HttpContext context = HttpContext.Current;
            string filePath = context.Server.MapPath(filename);
            string extension = Path.GetExtension(filename);

            ImageFormat format = GetImageFormat(extension);
            new Bitmap(filePath).Save(ms, format != null ? format as ImageFormat : ImageFormat.Bmp);

            HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
            result.Content = new ByteArrayContent(ms.ToArray());
    

  • Share

Disclaimer

Purpose of the code contained in snippets or available for download in this article is solely for learning and demo purposes. Author will not be held responsible for any failure or damages caused due to any other usage.

Comments for this article

comments powered by Disqus