Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rotating JPEGs in .NET with minimal loss of quality

I am attempting to support rotating JPEG images from ASP.NET MVC (in 90 degree increments). I am attempting to use System.Drawing (GDI+), however I am running into issues.

I tried using Image.RotateFlip which is able to rotate the image but causes a loss of quality. Even with an encoder quality of 100, there are still visible artifacts on the rotated image that weren't on the original image nor do they show up when I rotate it using other programs (Gimp, etc.).

using (Image image = Image.FromFile("C:\\source.jpg")) {
    ImageFormat sourceFormat = image.RawFormat;
    image.RotateFlip(RotateFlipType.Rotate90FlipNone);
    EncoderParameters encoderParams = null;
    try {
        if (sourceFormat == ImageFormat.Jpeg) {
            encoderParams = new EncoderParameters(1);
            encoderParams.Param[0] = new EncoderParameter(Encoder.Quality, 100L);
        }
        image.Save("C:\\target.jpg", GetEncoder(sourceFormat), encoderParams);
    } finally {
        if (encoderParams != null)
            encoderParams.Dispose();
    }
}

I found an article on transforming a JPEG without loss of information. Using Encoder.Transformation appears to be an option from .NET - however I cannot get it to cause any of my JPEG test images to rotate at all, whether or not the dimensions are a multiple of 16.

using (Image image = Image.FromFile("C:\\source.jpg")) {
    ImageFormat sourceFormat = image.RawFormat;
    EncoderParameters encoderParams = null;
    try {
        if (sourceFormat == ImageFormat.Jpeg) {
            encoderParams = new EncoderParameters(1);
            encoderParams.Param[0] = new EncoderParameter(Encoder.Transformation, 
                (long)EncoderValue.TransformRotate90);
        }
        image.Save("C:\\target.jpg", GetEncoder(sourceFormat), encoderParams);
    } finally {
        if (encoderParams != null)
            encoderParams.Dispose();
    }
}

Does anyone know how to successfully rotate a JPEG in .NET in 90 degree increments with minimal or no loss of quality using either of the above methods or another method? Thanks.

Also, here's my implementation of GetEncoder:

private ImageCodecInfo GetEncoder(ImageFormat format) {
    foreach (var info in ImageCodecInfo.GetImageEncoders())
        if (info.FormatID == format.Guid)
            return info;
    return null;
}

Edit:

I updated the above code to better match my actual code. The bug was in the following line:

if (sourceFormat == ImageFormat.Jpeg) {

It should have been:

if (sourceFormat.Guid == ImageFormat.Jpeg.Guid) {
like image 672
Mike Henry Avatar asked Jul 27 '09 06:07

Mike Henry


People also ask

Does rotating photos reduce quality?

Rotation by arbitrary angle always requires re-compression and also makes the picture softer, even if you use a non-compressed format (such as BMP) - the new pixels do not have exactly corresponding pixels on the non-rotated image and therefore have to be calculated based on weighted average of surrounding pixels.

Can you rotate JPEG?

In the Edit Pictures task pane, under Edit using these tools, click Rotate and Flip. Do one of the following: Click Rotate left or Rotate right. If you click the option more than once, the picture will continue to rotate in the same direction.

How do you rotate an image in JavaScript?

To rotate an image with JavaScript, access the image element with a method like getElementById() , then set the style. transform property to a string in the format rotate({value}deg) , where {value} is the clockwise angle of rotation in degrees.


1 Answers

Thanks for confirming that my posted code worked. This helped me isolate my problem. I feel stupid now. My actual code had a check for image format before setting encoderParams - but it had a bug:

if (sourceFormat == ImageFormat.Jpeg) {
    // set encoderParams here

I discovered the above conditional was always false so encoderParams wasn't being set. The fix was simple:

if (sourceFormat.Guid == ImageFormat.Jpeg.Guid) {
like image 71
Mike Henry Avatar answered Oct 19 '22 00:10

Mike Henry