This is a common enough operation, but a few factors conspire to make this more difficult than you may initially expect:
- We must use the Image.Save(String, ImageCodecInfo, EncoderParameters) method. There is no Image.Save that takes a compression value as a parameter.
- To obtain an ImageCodecInfo object for JPEG encoding, we must iterate through the collection returned from calling ImageCodecInfo.GetImageEncoders(). It would have been more convenient for this to have been a Dictionary, so we could retrieve an encoder by key (say its mime-type).
-
EncoderParameters can be quite difficult to fathom, as it breaks a few conventions (Param is singular, yet it represents a collection, for example).
The following example shows how to save off a JPEG image with a set compression value. It may be useful for you to extend this example into a class of your own, so you don't have to write this code again.
using System;
using System.Drawing;
using System.Drawing.Imaging;
namespace TestPrograms
{
class Program
{
/// <summary>
/// Obtain an image encoder suitable for a specific graphics format.
/// </summary>
/// <param name="imageType">One of: BMP, JPEG, GIF, TIFF, PNG.</param>
/// <returns>An ImageCodecInfo corresponding with the type requested,
/// or null if the type was not found.</returns>
static ImageCodecInfo GetImageEncoder(string imageType)
{
imageType = imageType.ToUpperInvariant();
foreach (ImageCodecInfo info in ImageCodecInfo.GetImageEncoders())
{
if (info.FormatDescription == imageType)
{
return info;
}
}
return null;
}
/// <summary>
/// Create a simple image for test purposes.
/// </summary>
/// <returns>A new Image, which should be disposed of after use.</returns>
static Image CreateTestImage()
{
Bitmap bmp = new Bitmap(100, 100);
using (Graphics g = Graphics.FromImage(bmp))
{
// Create a background
g.FillRectangle(Brushes.Wheat, 0, 0, 100, 100);
// Draw some text, which should show the effects of compression
Font font = new Font("Verdana", 16F, FontStyle.Bold);
StringFormat fmt = new StringFormat();
fmt.Alignment = StringAlignment.Center;
fmt.LineAlignment = StringAlignment.Center;
g.DrawString("Test", font, Brushes.DarkBlue,
new RectangleF(0, 0, 100, 100), fmt);
}
return bmp;
}
static void Main(string[] args)
{
// Use our method to retrieve a JPEG encoder
ImageCodecInfo jpegEncoder = GetImageEncoder("JPEG");
// Set the compression parameter of our encoder
EncoderParameters parms = new EncoderParameters(1);
parms.Param[0] = new EncoderParameter(Encoder.Compression, 40);
// Create an image, then save it as a compressed JPEG to disk
// NB: the 'using' construct disposes of the bitmap object
// so it can be garbage collected by the Runtime
using (Image testImage = CreateTestImage())
{
testImage.Save(@"C:\Test.jpg", jpegEncoder, parms);
}
}
}
}