获取图像方向并根据方向旋转
Posted
技术标签:
【中文标题】获取图像方向并根据方向旋转【英文标题】:Get Image Orientation and rotate as per orientation 【发布时间】:2015-01-08 07:33:30 【问题描述】:使用以下代码获取图像方向时遇到问题
string fileName = @"D:\...\...\01012015004435.jpeg";
int rotate = 0;
using (var image = System.Drawing.Image.FromFile(fileName))
foreach (var prop in image.PropertyItems)
if (prop.Id == 0x112)
if (prop.Value[0] == 6)
rotate = 90;
if (prop.Value[0] == 8)
rotate = -90;
if (prop.Value[0] == 3)
rotate = 180;
prop.Value[0] = 1;
在获得正确的方向后,我习惯于像这样旋转图像
private static RotateFlipType OrientationToFlipType(string orientation)
switch (int.Parse(orientation))
case 1:
return RotateFlipType.RotateNoneFlipNone;
break;
case 2:
return RotateFlipType.RotateNoneFlipX;
break;
case 3:
return RotateFlipType.Rotate180FlipNone;
break;
case 4:
return RotateFlipType.Rotate180FlipX;
break;
case 5:
return RotateFlipType.Rotate90FlipX;
break;
case 6:
return RotateFlipType.Rotate90FlipNone;
break;
case 7:
return RotateFlipType.Rotate270FlipX;
break;
case 8:
return RotateFlipType.Rotate270FlipNone;
break;
default:
return RotateFlipType.RotateNoneFlipNone;
但问题出在第一个代码中
prop.Id
我总是得到 [20625]
prop.Id == 20625
所以不是每次都满足条件 如果有任何问题或其他选择,请告诉我
谢谢
【问题讨论】:
您正在查看的图像是否指定了它们的方向?我不确定这是默认设置的属性(即你的 gravatar 的默认方向是什么?) 而不是检查每个图像PropertyItem
,你应该简单地查询你想要的,例如。 image.GetPropertyItem(0x112);
。如果旋转属性不存在,它将抛出异常(您可以捕获和处理)。并非所有图像文件都具有旋转属性。另请注意,PropertyItem.Type
值应为 3(16 位整数),Len
值至少为 2。虽然您拥有的代码应该可以工作,但恕我直言,继续使用 BitConverter
更正确将Value
数组中的前两个字节转换为Int16
,以防有一些奇怪的值 > 255。
您好,感谢您的回复,实际上我是 wcf 服务中的服务提供商和 Web 服务。 android 和 ios 开发人员向我发送了图像,根据图像我必须旋转或裁剪。所以他们需要设置图像属性?
如果您使用Image.FromStream
读取图像,请注意。您必须将 useEmbeddedColorManagement
设置为 true
才能正常工作。否则,PropertyItems
将为空。示例:var image = Image.FromStream(memoryStream, true);
【参考方案1】:
其他答案和 cmets 中可能有足够的信息将这些信息放在一起,但这是一个有效的代码示例。
此扩展方法将采用 System.Drawing
Image
,读取其 Exif Orientation 标签(如果存在),并翻转/旋转它(如果需要)。
private const int exifOrientationID = 0x112; //274
public static void ExifRotate(this Image img)
if (!img.PropertyIdList.Contains(exifOrientationID))
return;
var prop = img.GetPropertyItem(exifOrientationID);
int val = BitConverter.ToUInt16(prop.Value, 0);
var rot = RotateFlipType.RotateNoneFlipNone;
if (val == 3 || val == 4)
rot = RotateFlipType.Rotate180FlipNone;
else if (val == 5 || val == 6)
rot = RotateFlipType.Rotate90FlipNone;
else if (val == 7 || val == 8)
rot = RotateFlipType.Rotate270FlipNone;
if (val == 2 || val == 4 || val == 5 || val == 7)
rot |= RotateFlipType.RotateNoneFlipX;
if (rot != RotateFlipType.RotateNoneFlipNone)
img.RotateFlip(rot);
【讨论】:
这在我的开发机器上完美运行。我将它上传到生产中,对于同一张图片,它就像文件没有 Exif 信息一样。你知道为什么会这样吗?System.Drawing
在下面使用 Windows Imaging Component,因此您的开发和生产 Windows 安装之间的编解码器功能可能存在一些差异。如果您在非 Windows 机器上使用 System.Drawing
,同样适用,其中将有一个兼容层。
我在这里提出了一个问题,以防您了解更多信息:***.com/questions/53546113/… 谢谢!
谢谢!我注意到,当我尝试显示 iphone 图像时,它们会偏向一边。我做了一个重新调整大小来去除 exif 数据(这是我想要的,这使得显示正确)......但它以错误的方式保存它们。完美修复我的好人
您可能还想使用SetPropertyItem
将exifOrientationID
设置为0
。【参考方案2】:
使用以下内容:
img.PropertyIdList.Contains(orientationId)
检查 Exif 标签是否存在。
img.GetPropertyItem(orientationId)
得到它(经过上述检查,否则你会得到一个ArgumentException
)。
img.SetPropertyItem(pItem)
进行设置。
我编写了一个简单的帮助类来完成所有这些工作:您可以查看full source code here。
其他信息和快速案例研究也可以在我博客上的以下帖子中找到:
Change image orientation for iPhone and/or Android pics in NET C#
【讨论】:
我点击了链接,但没有找到您解决方案的完整源代码。【参考方案3】:您可以使用此链接http://regex.info/exif.cgi 检查您的图像嵌入元数据。如果在 EXIF 表中没有找到“0x0112”,则说明图片不包含旋转属性。
【讨论】:
以上是关于获取图像方向并根据方向旋转的主要内容,如果未能解决你的问题,请参考以下文章