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
Right-click the image and select Details to reveal a screen with metadata, including EXIF data, that you can adjust if the image supports it. Force a preferred orientation. Rotate the image, then save it. That process reconstructs the image along the requested dimensions.
If an image contains the wrong image orientation EXIF data, or if that data is stripped in the upload process for whatever reason, it will display as rotated. To fix the EXIF orientation, open the image in your image editing program.
To perform a lossless left/right rotate or vertical/horizontal flip, go to Tools > JPEG Lossless Rotate. Alternatively, you can also find the Tools menu by right clicking on the image. The rotate clockwise or counterclockwise icons are also lossless for JPEG files.
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 changes the image to the correctly 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!
Pictures coming from a camera can contain so called EXIF metadata. This EXIF metadata can have an "orientation" tag, which many image viewing programs look at and rotate the picture accordingly when showing it. But the orientation of the image data itself remains unchanged. So in case you images come from a camera and images in landscape orientation are affected by what you describe, chances are that it is doe to the EXIF orientation tag. This is an article about this tag. Maybe there's C# code around that can help you to handle the EXIF tag, I did not check.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With