Introduction
This sample demonstrates the GetImageEncoders()
and GetImageDecoders()
methods in the System.Drawing.Imaging.ImageCodecInfo
class, presenting the results in two dynamically generated HTML tables.
I came up with this example while investigating some aspects of the System.Drawing.Imaging
namespace recently. My intent was to show what built-in image codecs are available in .NET, but the result is a nice example of dynamic HTML table generation and of using the System.Reflection
namespace.
Background
The term CODEC is an acronym for "compression/decompression" and is used for modules that compress and/or decompress various types of data. An image codec, as you might guess, is a codec applied to a digital image. The .NET Framework provides the ImageCodecInfo
class to encapsulate such a module as part of the System.Drawing.Imaging
namespace. The Bitmap
class includes a Save()
method that accepts an ImageCodecInfo
instance and saves the current bitmap in the format supported by the given codec.
At present, it is not possible to build and add customer codec modules to .NET. A number of built-in compression and decompression modules, commonly called encoders and decoders, are provided that cover the most common file formats. These codecs should work well for most digital imaging applications you may wish to build.
Using the code
The project can be downloaded from the link at the top of this page. You will need Visual Studio .NET or other compiler, of course, and access to an Internet Information Server (IIS) to act as the server machine.
To run the project from Visual Studio .NET, create a new ASP.NET Web Application project called "ImageCodecs." Close the new solution and replace the project's directory (also called "ImageCodecs") on the server with the contents of the downloaded zip file. Reload the project in Visual Studio .NET and you should be ready to go.
Points of Interest
There are two primary methods in the code, one for each type of codec. The method that loads the encoder table is shown here. The method for the decoder table is quite similar.
private void LoadEncoderTable()
{
EncoderTable.Rows.Clear();
Type t = typeof(ImageCodecInfo);
(1) PropertyInfo[] properties = t.GetProperties();
HtmlTableRow headerRow = new HtmlTableRow();
(2) BuildHeaderRow(headerRow, properties);
EncoderTable.Rows.Add(headerRow);
ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();
foreach (ImageCodecInfo info in encoders)
{
HtmlTableRow row = new HtmlTableRow();
(3) BuildTableRow(row, properties, info);
EncoderTable.Rows.Add(row);
}
}
As you can see, (1) the Type.GetProperties()
method from the System.Reflection
namespace is used to retrieve the array of properties for the ImageCodecInfo
class type. This array is used both (2) to generate the table header and (3) to generate a table row for each encoder.
The BuildHeaderRow()
and BuildTableRow()
methods use reflection to enumerate the properties from the ImageCodecInfo
class. The BuildTableRow()
method is slightly more complex, and is shown here.
private void BuildTableRow(HtmlTableRow row, PropertyInfo[] properties, object obj)
{
foreach (PropertyInfo prop in properties)
{
HtmlTableCell cell = new HtmlTableCell();
(4) object propValue = prop.GetValue(obj, null);
if (propValue != null)
cell.InnerText = propValue.ToString();
else
cell.InnerText = "<none>";
row.Cells.Add(cell);
}
}
Note the use (4) of the GetValue()
method to retrieve the value of the property corresponding to the current PropertyInfo
object. We simply display the ToString()
result of this value in the table, unless the value is null, in which case we display the string "<none>" instead.
For More Information
The ImageCodeInfo
class in .NET is based on the ImageCodeInfo
class in GDI+. The .NET versions are not documented very extensively, but you can learn a lot from the Platform SDK documentation. A good place to start for more information on this topic is the article "Using Image Encoders and Decoders" in the Platform SDK GDI+ documentation.
Microsoft also provides the microsoft.public.dotnet.framework.drawing newsgroup for questions and comments on the .NET drawing namespaces.