图像在PictureBox中旋转

msh*_*hwf 4 c# picturebox winforms

正如问题所暗示的,当我将图像加载到pictureBox(使用对话框)时,它不会显示为其原始外观.在这个屏幕截图中,左边的图像是我加载到pictureBox中的图像(右边).

试图知道是什么原因导致我使用Paint应用程序绘制图像并使用Windows照片查看器旋转它,旋转的图像按原样(旋转)加载,也就是说,有些图片只是精装,其他图片是旋转的!我无法弄清楚为什么?! 在此输入图像描述

Pet*_*iho 8

如果没有原始图像数据,就无法确定发生了什么.但很明显,在某些时候,处理图像的一些软件使用EXIF方向属性来旋转图像,而不是实际修改图像数据本身.这可能是照片查看器或某些处理照片的工具.

以下是可用于检测图像方向的代码,由拍摄照片的相机记录在EXIF数据中:

static ImageOrientation GetOrientation(this Image image)
{
    PropertyItem pi = SafeGetPropertyItem(image, 0x112);

    if (pi == null || pi.Type != 3)
    {
        return ImageOrientation.Original;
    }

    return (ImageOrientation)BitConverter.ToInt16(pi.Value, 0);
}

// A file without the desired EXIF property record will throw ArgumentException.
static PropertyItem SafeGetPropertyItem(Image image, int propid)
{
    try
    {
        return image.GetPropertyItem(propid);
    }
    catch (ArgumentException)
    {
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

哪里:

/// <summary>
/// Possible EXIF orientation values describing clockwise
/// rotation of the captured image due to camera orientation.
/// </summary>
/// <remarks>Reverse/undo these transformations to display an image correctly</remarks>
public enum ImageOrientation
{
    /// <summary>
    /// Image is correctly oriented
    /// </summary>
    Original = 1,
    /// <summary>
    /// Image has been mirrored horizontally
    /// </summary>
    MirrorOriginal = 2,
    /// <summary>
    /// Image has been rotated 180 degrees
    /// </summary>
    Half = 3,
    /// <summary>
    /// Image has been mirrored horizontally and rotated 180 degrees
    /// </summary>
    MirrorHalf = 4,
    /// <summary>
    /// Image has been mirrored horizontally and rotated 270 degrees clockwise
    /// </summary>
    MirrorThreeQuarter = 5,
    /// <summary>
    /// Image has been rotated 270 degrees clockwise
    /// </summary>
    ThreeQuarter = 6,
    /// <summary>
    /// Image has been mirrored horizontally and rotated 90 degrees clockwise.
    /// </summary>
    MirrorOneQuarter = 7,
    /// <summary>
    /// Image has been rotated 90 degrees clockwise.
    /// </summary>
    OneQuarter = 8
}
Run Code Online (Sandbox Code Playgroud)

GetOrientation()上面的方法是作为扩展方法编写的,但当然可以将其称为普通静态方法.无论哪种方式,只需将Bitmap刚从文件中打开的对象传递给它,它将返回存储在文件中的EXIF方向(如果有的话).

有了这些,您可以根据需要旋转图像.


Rez*_*aei 6

在Windows Photo Viewer中查看图像时,如果具有Exif方向数据,它将自动校正图像方向。PictureBox不支持此类功能。您可以创建一个自定义PictureBox,即使图像具有方向数据,该自定义也可以正确显示图像:

using System.Linq;
using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;
Run Code Online (Sandbox Code Playgroud)
public class MyPictureBox : PictureBox
{
    private void CorrectExifOrientation(Image image)
    {
        if (image == null) return;
        int orientationId = 0x0112;
        if (image.PropertyIdList.Contains(orientationId))
        {
            var orientation = (int)image.GetPropertyItem(orientationId).Value[0];
            var rotateFlip = RotateFlipType.RotateNoneFlipNone;
            switch (orientation)
            {
                case 1: rotateFlip = RotateFlipType.RotateNoneFlipNone; break;
                case 2: rotateFlip = RotateFlipType.RotateNoneFlipX; break;
                case 3: rotateFlip = RotateFlipType.Rotate180FlipNone; break;
                case 4: rotateFlip = RotateFlipType.Rotate180FlipX; break;
                case 5: rotateFlip = RotateFlipType.Rotate90FlipX; break;
                case 6: rotateFlip = RotateFlipType.Rotate90FlipNone; break;
                case 7: rotateFlip = RotateFlipType.Rotate270FlipX; break;
                case 8: rotateFlip = RotateFlipType.Rotate270FlipNone; break;
                default: rotateFlip = RotateFlipType.RotateNoneFlipNone; break;
            }
            if (rotateFlip != RotateFlipType.RotateNoneFlipNone)
            {
                image.RotateFlip(rotateFlip);
                image.RemovePropertyItem(orientationId);
            }
        }
    }
    [Localizable(true)]
    [Bindable(true)]
    public new Image Image
    {
        get { return base.Image; }
        set { base.Image = value; CorrectExifOrientation(value); }
    }
}
Run Code Online (Sandbox Code Playgroud)