« Quicken 2004 has bugs and Intuit's support is painful | Main | 12 rules to clarify HttpRequest & Uri properties »

The Right Way to Rotate JPEGs

The combination of the FromFile, RotateFlip and Save methods from System.Drawing.Image is an obvious approach when looking for functions to rotate JPEGs by 90 degrees, but there are reasons for not doing it this way:

      public static void SimpleRotate90(string inFile, string outFile, bool clockwise) {

            using (Image image = Image.FromFile(inFile)) {

                  image.RotateFlip(clockwise ? RotateFlipType.Rotate90FlipNone : RotateFlipType.Rotate270FlipNone);

                  image.Save(outFile);

            }

      }

Why isn’t this a good solution? Here’s why:

1.      The saved image is typically much larger than the original.

2.      While the image displays fine in IE and some other tools, Photoshop 8 complains about an “invalid jpeg marker” in the file and won’t open it.

3.      It’s slower than it needs to be.

 

One solution is to let the Save method do more of the work by passing it an Encoder parameter that tells it to transform the image as it is saved.

The code looks like this:

      using System.Drawing;

      using System.Drawing.Imaging;

 

      ...

 

      public static ImageCodecInfo GetImageCodecInfo(ImageFormat format) {

            foreach (ImageCodecInfo info in ImageCodecInfo.GetImageEncoders())

                  if (info.FormatID == format.Guid) return info;

            return null;

      }

 

 

      public static void Rotate90(string inFile, string outFile, bool clockwise) {

            using (Image image = Image.FromFile(inFile)) {

                  EncoderParameters eps = new EncoderParameters(1);

                  EncoderValue v = clockwise ? EncoderValue.TransformRotate90 : EncoderValue.TransformRotate270;

                  eps.Param[0] = new EncoderParameter(Encoder.Transformation, (long) v);

                  image.Save(outFile, GetImageCodecInfo(ImageFormat.Jpeg), eps);

            }

      }

 

Comments about this implementation:

1.      The saved image is about the same size as the original.

2.      Photoshop 8 seems happy.

3.      The using statement guarantees that image.Displose() gets called which guarantees the inFile gets released.

4.      The helper function GetImageCodecInfo uses the ImageFormat class instead of relying on mime type strings.

 

 

 

Comments

Interesting. I recently wrote a bit of code which rotated a gif similar to your first block of code, didn't try opening it in photoshop so I wasn't aware of the issues. Never noticed the file size increase either, Cheers!

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)