8

I have a web application on which users can upload profile picture by taking the picture directly by mobile phones. Because of EXIF orientation of the images, the frontend must transform image (rotate/flip) before showing the picture. However, I want the perform the transformation in the backend before saving the picture to avoid the transformation in the frontend. Backend is .net core 2.0 application written in c#.

Does anyone have suggestion regarding the library which can be used to access EXIF data and do the transformation.

As of now, I have found https://github.com/SixLabors/ImageSharp and going through its documentation on how to use it.

dudedev
  • 451
  • 1
  • 5
  • 19
  • 1
    Stack Overflow is not the place for sourcing or getting recommendations on libraries. FWIW, ImageSharp is a good library, so just try it. If it doesn't do everything you need, research something else. If you run into issues, you can ask *specific* questions about those. – Chris Pratt Apr 24 '18 at 18:02

2 Answers2

15

There's a method for that already in the ImageSharp library. AutoOrient() that handles everything for you.

Docs

private byte[] TransformAvatarIfNeeded(byte[] imageInBytes)
{
    using (var image = Image.Load(imageInBytes, out var imageFormat ))
    {
        image.Mutate(x => x.AutoOrient());
        return ImageToByteArray(image, imageFormat);
    }
}
James South
  • 10,147
  • 4
  • 59
  • 115
11

Finally, I got it working with ImageSharp library. It might be helpful for others.

    private byte[] TransformAvatarIfNeeded(byte[] imageInBytes)
    {
        using (var image = Image.Load(imageInBytes))
        {
            ExifValue exifOrientation = image.MetaData?.ExifProfile?.GetValue(ExifTag.Orientation);

            if (exifOrientation == null) return imageInBytes;

            RotateMode rotateMode;
            FlipMode flipMode;
            SetRotateFlipMode(exifOrientation, out rotateMode, out flipMode);

            image.Mutate(x => x.RotateFlip(rotateMode, flipMode));
            image.MetaData.ExifProfile.SetValue(ExifTag.Orientation, (ushort)1);

            var imageFormat = Image.DetectFormat(imageInBytes);

            return ImageToByteArray(image, imageFormat);
        }
    }

    private byte[] ImageToByteArray(Image<Rgba32> image, IImageFormat imageFormat)
    {
        using (var ms = new MemoryStream())
        {
            image.Save(ms, imageFormat);
            return ms.ToArray();
        }
    }

    private void SetRotateFlipMode(ExifValue exifOrientation, out RotateMode rotateMode, out FlipMode flipMode)
    {
        var orientation = exifOrientation.Value.ToString();

        switch (orientation)
        {
            case "2":
                rotateMode = RotateMode.None;
                flipMode = FlipMode.Horizontal;
                break;
            case "3":
                rotateMode = RotateMode.Rotate180;
                flipMode = FlipMode.None;
                break;
            case "4":
                rotateMode = RotateMode.Rotate180;
                flipMode = FlipMode.Horizontal;
                break;
            case "5":
                rotateMode = RotateMode.Rotate90;
                flipMode = FlipMode.Horizontal;
                break;
            case "6":
                rotateMode = RotateMode.Rotate90;
                flipMode = FlipMode.None;
                break;
            case "7":
                rotateMode = RotateMode.Rotate90;
                flipMode = FlipMode.Vertical;
                break;
            case "8":
                rotateMode = RotateMode.Rotate270;
                flipMode = FlipMode.None;
                break;
            default:
                rotateMode = RotateMode.None;
                flipMode = FlipMode.None;
                break;
        }
dudedev
  • 451
  • 1
  • 5
  • 19