EmguCV - how to specify jpeg quality when saving image?

sergtk picture sergtk · Oct 27, 2011 · Viewed 14.9k times · Source

I save jpeg image using the following C# EmguCV code:

Emgu.CV.Image<Gray, byte> image
...
image.Save("imageName.jpg");

But image is stored in extremally low quality (1 color square per 8x8 pixels).

When I save bmp all are ok:

Emgu.CV.Image<Gray, byte> image
...
image.Save("imageName.bmp");

How to increase jpeg quality when using Emgu.Cv.Image.Save or should I call other function? Why is default quality so low?

Tried to ask on EmguCV forum, but it is unreachable.

Answer

Chris picture Chris · Oct 27, 2011

EMGU only has image.Save(filename) therefore you have to use the .Net method of saving the image. This code is derived from here. I separated the code for ease this code opens a file then attempts to save it. This is the function you interested in saveJpeg(SaveFile.FileName, img.ToBitmap(), 100);. Based on the function saveJpeg(string path, Bitmap img, long quality).

open.Filter = "Image Files (*.tif; *.dcm; *.jpg; *.jpeg; *.bmp)|*.tif; *.dcm; *.jpg; *.jpeg; *.bmp";
if (open.ShowDialog() == DialogResult.OK)
{
    Image<Bgr, Byte> img = new Image<Bgr, Byte>(open.FileName);
    SaveFileDialog SaveFile = new SaveFileDialog();
    if (SaveFile.ShowDialog() == DialogResult.OK)
    {
        saveJpeg(SaveFile.FileName, img.ToBitmap(), 100);
    }
}

Now to get the code for that function comes from the following you can copy and paste this into your project don't forget the using statement at the top of your code.

using System.Drawing.Imaging;

private void saveJpeg(string path, Bitmap img, long quality)
{
    // Encoder parameter for image quality

    EncoderParameter qualityParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);

    // Jpeg image codec
    ImageCodecInfo jpegCodec = this.getEncoderInfo("image/jpeg");

    if (jpegCodec == null)
    return;

    EncoderParameters encoderParams = new EncoderParameters(1);
    encoderParams.Param[0] = qualityParam;

    img.Save(path, jpegCodec, encoderParams);
}

private ImageCodecInfo getEncoderInfo(string mimeType)
{
    // Get image codecs for all image formats
    ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();

    // Find the correct image codec
    for (int i = 0; i < codecs.Length; i++)
    if (codecs[i].MimeType == mimeType)
    return codecs[i];
    return null;
}

This is the best method for EMGU if you get stuck let me know.

Hope this Helps,

Chris