Search code examples
c#resizedrawingjpegrotation

C# Rotating JPG without losing too much quality


So I'm reading in files from a directory, figuring out which way they need to be rotated. Rotating and then saving. That part works... The issue is, after it saves the file it gets recompressed and I go from 1.5meg images to 250k images. I need to keep the file size around the original. I tried using jhead.exe and calling it from a command line but couldn't get any of my arguments to pass in correctly. Here's my code snipit to detect, rotate, and save.

foreach (FileInfo f in dir.GetFiles("*.jpg"))
{
    try
    {
        string ExportName = "";

        Bitmap originalImage = new Bitmap(f.FullName.ToString());

        Info inf = new Info(originalImage);

        gma.Drawing.ImageInfo.Orientation orientation = gma.Drawing.ImageInfo.Orientation.TopLeft;
        try
        {
            orientation = inf.Orientation;
        }
        catch
        {
            orientation = gma.Drawing.ImageInfo.Orientation.TopLeft;
        }

        originalImage = CheckRotation(originalImage, orientation);

        progressBar.Value = progressBar.Value + 1;
        originalImage.Save(f.FullName.ToString(), ImageFormat.Jpeg);
        Application.DoEvents();


    }

private Bitmap CheckRotation(Bitmap inputImage, gma.Drawing.ImageInfo.Orientation orientation)
{

    Bitmap rotatedImage = inputImage;

    switch (orientation)
    {
        case gma.Drawing.ImageInfo.Orientation.LeftBottom:
            rotatedImage.RotateFlip(RotateFlipType.Rotate90FlipXY);
            break;
        case gma.Drawing.ImageInfo.Orientation.RightTop:
            rotatedImage.RotateFlip(RotateFlipType.Rotate90FlipNone);
            break;
        default:
            break;
    }
    return rotatedImage;
}

Solution

  • ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders(); 
    ImageCodecInfo ici = null; 
    
    foreach (ImageCodecInfo codec in codecs)
    { 
        if (codec.MimeType == "image/jpeg") 
        ici = codec; 
    } 
    
    EncoderParameters ep = new EncoderParameters(); 
    ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)100);
    
    originalImage.Save(f.FullName.ToString(), ici, ep);
    

    This will use 100% quality - but beware, jpegs are still lossy compression - try using a png if you need loss-less quality.