Elliott Addi Elliott Addi -4 years ago 221
C# Question

Getting correct Image rotation

I have a simple problem: When I load an image to a windows form

PictureBox
some pictures are rotated and others are not.

Basically, a user selects a picture with an
OpenFileDialog
and when the picture is selected:

private void OpenFD_FileOk(object sender, CancelEventArgs e)
{
Image image = Image.FromFile(openFD.FileName);
PB_profile.Image = image;
}


And yes I checked the original image rotation

EDIT:

I changed the
PictureBox
property
SizeMode
to
StretchImage

Answer Source

If the pictures contains exif data the PropertyItems should include the orientation tag.

It encodes the rotation/flipping necessary to display the image correctly:

PropertyTagOrientation

Image orientation viewed in terms of rows and columns.

Tag 0x0112

1 - The 0th row is at the top of the visual image, and the 0th column is the visual left side.
2 - The 0th row is at the visual top of the image, and the 0th column is the visual right side.
3 - The 0th row is at the visual bottom of the image, and the 0th column is the visual right side.
4 - The 0th row is at the visual bottom of the image, and the 0th column is the visual left side.
5 - The 0th row is the visual left side of the image, and the 0th column is the visual top.
6 - The 0th row is the visual right side of the image, and the 0th column is the visual top.
7 - The 0th row is the visual right side of the image, and the 0th column is the visual bottom.
8 - The 0th row is the visual left side of the image, and the 0th column is the visual bottom.

Here is a function to retrieve a PropertyItem:

PropertyItem getPropertyItemByID(Image img, int Id)
{
    return img.PropertyItems.Select(x => x).FirstOrDefault(x => x.Id == Id);
}

Here is an example of using the GDI+ RotateFlip method to adjust an image on the fly:

void Rotate(Bitmap bmp)
{
    PropertyItem pi = bmp.PropertyItems.Select(x => x)
                                       .FirstOrDefault(x => x.Id == 0x0112);
    if (pi == null) return; 

    byte o = pi.Value[0];

    if (o==2) bmp.RotateFlip(RotateFlipType.RotateNoneFlipX);
    if (o==3) bmp.RotateFlip(RotateFlipType.RotateNoneFlipXY);
    if (o==4) bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);
    if (o==5) bmp.RotateFlip(RotateFlipType.Rotate90FlipX);
    if (o==6) bmp.RotateFlip(RotateFlipType.Rotate90FlipNone);
    if (o==7) bmp.RotateFlip(RotateFlipType.Rotate90FlipY);
    if (o==8) bmp.RotateFlip(RotateFlipType.Rotate90FlipXY);
}

It returns the rotated version..

I have tested to values with this nice set of sample images.

Note: The code will only work if the images actually contain the orientation tag. If they don't, maybe because they are scans, then it will do nothing.

Note 2 You wrote I checked the original image rotation. This is not so simple: The explorer will display the images already rotated, so here they all look right and even inspecting the properties doesn't reveal the orientation!

Usually, when no exif data are present, the PropertyTagOrientation tag is present but only has the default value of 1..

Update: If the image doesn't have the PropertyTagOrientation here is how you can add one:

    using System.Runtime.Serialization;
    ..

    pi = (PropertyItem)FormatterServices
        .GetUninitializedObject(typeof(PropertyItem));

    pi.Id = 0x0112;   // orientation
    pi.Len = 2;
    pi.Type = 3;
    pi.Value = new byte[2] { 1, 0 };

    pi.Value[0] = yourOrientationByte;

    yourImage.SetPropertyItem(pi);

Kudos to @ne1410s's excellent answer here!.

Note that adding PropertyItems to an image does not add exif data; the two are different tag sets!

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download