c# - 获得正确的图像旋转

标签 c# image rotation

<分区>

我有一个简单的问题:当我将图像加载到 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 数据;两者是不同的标签集!

关于c# - 获得正确的图像旋转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42971094/

相关文章:

Android OpenGL 以触摸移动的方向旋转立方体

c# - Windows7 上语音识别 C# WPF 应用程序的两个问题

c# - 如何在C#中禁用鼠标点击

iOS:UIImagePNGRepresentation().writeToFile 未写入预期目录

ipad - 在 iPad 上的 IOS 6 中,初始旋转始终为纵向,之后始终正确旋转

c++ - 旋转使用 OpenGL 绘制的 2D 对象

c# - 已为应用付费的用户的应用内购买

c# - 在 Windows 服务中保持 C# Mutex 事件

java - 在 JPanel 中嵌入两个图像(重叠)

image - 如何使用边界分割具有多部分/相关MIME类型的电子邮件?