Search code examples
c#image-processingopencvemgucv

EmguCV - how to specify jpeg quality when saving image?


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.


Solution

  • 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