.NET Saving jpeg with the same quality as it was l

2019-03-12 18:39发布

问题:

I have a cannon digital camera and I set it to take pictures with superfine quality and it outputs a .jpg file 3 mega in size. If I load it like this in ASP.NET(this is useful to change it's dpi resolution or crop it or whaterver)

imgPicture = Image.FromFile(Config.WorkDirectory + this.TempPhotoName);
bmpPicture = new Bitmap(imgPicture);

and then I save it again like this:

bmpModified.Save(Config.WorkDirectory + this.TempPhotoName,System.Drawing.Imaging.ImageFormat.Jpeg);

it outputs a jpg that is only 700KB or so in size. There is a loss of quality.

I also tried saving it like this:

bmpPicture.Save(Config.WorkDirectory + this.TempPhotoName, codecJpeg, encparams);

where codecJpeg is

ImageCodecInfo codecJpeg = this.getEncoderInfo("image/jpeg");


    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;
    }

and encparams:

EncoderParameters encparams = new EncoderParameters(1);
encparams.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 97L);

This way the size(and I suspect also the quality) is maintained but I am inputing the quality by hand.

I want to ask:

Is there a way to save the image with the same quality as it was loaded without hardcoding the quality value?

Thank you in advance

回答1:

So it sounds like you know how to set the quality, you really just need to know how to fetch the quality from the original image?

I suspect that Image.PropertyItems is your friend, if the quality is in the metadata to start with. (I don't know if there's even a standard scale for quality within JPEG encoders.)

EDIT: I've just checked, and a jpeg I downloaded didn't have any tags for quality.

One option might be to work out how big the file should end up to have roughly the same quality, and then save it several times, doing a binary search to work out the most appropriate quality. Icky, but it might just work.

I have a sneaking suspicion that there isn't a way to just preserve the original quality setting, although I don't have very good grounds for that suspicion...



回答2:

You must use the additional parameters which tell GDI+ to detect the color scheme.

For instance:

using (var img = Image.FromStream(fileupload.InputStream, true,true))
{
    img.Save(fileOnDisk, ImageFormat.Jpeg);
}

using (var img = Image.FromFile("yourimage", true))
{
    img.Save(fileOnDisk, ImageFormat.Jpeg);
}


回答3:

Read here how to save image without re-encoding image: How-to: Re-encode a JPEG Image with Metadata.

However, if you do cropping or another image manipulation it impossible to do it without quality loss (well technically it is possible to do loss-less crop, if you work with boundaries that multiply of 16, but AFAIK it is cannot be done with libraries available in .net).