获得正确的图像旋转

时间:2017-03-23 08:48:12

标签: c# image rotation

我有一个简单的问题:当我将图像加载到窗体PictureBox时,某些图片会被旋转,而其他图片则不会。

基本上,用户选择带有OpenFileDialog的图片以及选择图片的时间:

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

是的,我检查了原始图像旋转

编辑:
我将PictureBox属性SizeMode更改为StretchImage

2 个答案:

答案 0 :(得分:6)

如果图片包含exif data,则PropertyItems应包含方向标记。

它对正确显示图像所需的旋转/翻转进行编码:

  

PropertyTagOrientation

     

按行和列查看图像方向。

     

标签0x0112

     

1 - 第0行位于顶部   视觉图像,第0列是视觉左侧   2 - 第0   row位于图像的可视顶部,第0列是   视觉右侧。
  3 - 第0行位于视觉底部   图像,第0列是视觉右侧   4 - 第0行   位于图像的视觉底部,第0列是视觉效果   左侧。
  5 - 第0行是图像的视觉左侧,和   第0列是视觉顶部   6 - 第0行是视觉右侧   图像的一侧,第0列是视觉顶部   7 - 第0   row是图像的可视右侧,第0列是   视觉底部。
  8 - 第0行是图像的视觉左侧,   第0列是视觉底部。

这是一个检索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数据;这两个是不同的标签集!

答案 1 :(得分:2)

来自相机的图片可以包含所谓的EXIF元数据。此EXIF元数据可以具有&#34;方向&#34;标签,许多图像查看程序查看并在显示时相应地旋转图片。但是图像数据本身的方向保持不变。 因此,如果您的图像来自相机并且横向图像受到您描述的影响,则可能是EXIF方向标记。 This is an article关于此标记。 也许那里的C#代码可以帮助你处理EXIF标签,我没有检查。