我有一个简单的问题:当我将图像加载到 Windows 窗体 PictureBox
时,一些图片会旋转,而另一些则不会。
基本上,用户使用 OpenFileDialog
选择一张图片,当图片被选中时:
private void OpenFD_FileOk(object sender, CancelEventArgs e)
{
Image image = Image.FromFile(openFD.FileName);
PB_profile.Image = image;
}
是的,我检查了原始图像旋转
编辑:
我将 PictureBox
属性 SizeMode
更改为 StretchImage
如果图片包含exif data PropertyItems
应包含 orientation 标签。
它对正确显示图像所需的旋转/翻转进行编码:
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.
这是一个检索 PropertyItem
的函数:
PropertyItem getPropertyItemByID(Image img, int Id)
{
return
img.PropertyItems.Select(x => x).FirstOrDefault(x => x.Id == Id);
}
下面是使用 GDI+ RotateFlip
方法动态调整图像的示例:
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);
}
它将图像更改为正确旋转的版本..
我已经用 this nice set of sample images 测试了值.
注意:该代码仅在图像实际包含方向标签时才有效。如果他们不这样做,可能是因为他们是扫描件,那么它将什么都不做。
注释 2 你写的 我检查了原始图像旋转。 这不是那么简单:资源管理器将显示已经旋转的图像,所以在这里它们看起来都是正确的并且即使检查属性也不会揭示方向!
通常,当不存在 exif 数据时,PropertyTagOrientation
标签存在,但只有默认值 1
..
更新:
如果图像没有有PropertyTagOrientation
,您可以通过以下方式添加一个:
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);
感谢@ne1410s 的出色 answer here! .
请注意,向图像添加 PropertyItems
不会添加 exif 数据;两者是不同的标签集!