デジカメで撮影した画像の向きを調整する

デジカメを横向きにして撮影すると、当然だが画像は横向きになる。後で画像をまとめて処理する時に、時々横を向いている画像があると都合が悪い。そういうわけで、EXIFヘッダーから画像の向きを判定して自動的に回転させるコードを書いてみた。

コードはこちら。使いたい人はご自由にどうぞ。

using System;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;

namespace JpegRotator
{
    public class JpegRotator : IDisposable
    {
        #region declarations for Exif properties
        private enum ExifOrientation
        {
            ORIENTATION_TOP_LEFT = 1,
            ORIENTATION_TOP_RIGHT = 2,
            ORIENTATION_BOTTOM_RIGHT = 3,
            ORIENTATION_BOTTOM_LEFT = 4,
            ORIENTATION_LEFT_TOP = 5,
            ORIENTATION_RIGHT_TOP = 6,
            ORIENTATION_RIGHT_BOTTOM = 7,
            ORIENTATION_LEFT_BOTTOM = 8,
        }
        #endregion declarations for Exif properties

        private readonly Image image;
        private readonly string filePath;

        public JpegRotator(string filePath)
        {
            this.filePath = filePath;

            using (var stream = new FileStream(filePath, FileMode.Open))
            {
                image = Bitmap.FromStream(stream);
                stream.Flush();
                AdjustOrientation();
            }
        }

        private void AdjustOrientation()
        {
            var orientation = ExifOrientation.ORIENTATION_TOP_LEFT;

            try
            {
                const int ID_ORIENTATION = 0x0112;
                var propItem = image.GetPropertyItem(ID_ORIENTATION);
                orientation = (ExifOrientation)BitConverter.ToInt16(propItem.Value, 0);

                var flip = RotateFlipType.RotateNoneFlipNone;
                switch (orientation)
                {
                    case ExifOrientation.ORIENTATION_BOTTOM_LEFT:
                        flip = RotateFlipType.RotateNoneFlipY;
                        break;
                    case ExifOrientation.ORIENTATION_RIGHT_TOP:
                        flip = RotateFlipType.Rotate90FlipNone;
                        break;
                    case ExifOrientation.ORIENTATION_LEFT_BOTTOM:
                        flip = RotateFlipType.Rotate270FlipNone;
                        break;
                    default:
                        return;
                }
                image.RotateFlip(flip);

                propItem.Value = BitConverter.GetBytes((short)ExifOrientation.ORIENTATION_TOP_LEFT);
                image.SetPropertyItem(propItem);
            }
#pragma warning disable 168
            catch (Exception e)
            {
                return;
            }
#pragma warning restore 168
        }

        public void Save()
        {
            Save(this.filePath);
        }

        public void Save(string filePath)
        {
            image.Save(filePath, ImageFormat.Jpeg);
        }

        public void Dispose()
        {
            if (image != null) image.Dispose();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Array.ForEach(args, f => new JpegRotator(f).Save());
        }
    }
}