resize时,某些图像正在旋转
简而言之,以下代码的目的是根据目标大小和乘数(1x,2x,3x)调整图像大小。 这工作正常,除了某些原因我还没有确定一些图像正在旋转。
public void ResizeImage(TargetSize targetSize, ResizeMultiplier multiplier, Stream input, Stream output) { using (var image = Image.FromStream(input)) { // Calculate the resize factor var scaleFactor = targetSize.CalculateScaleFactor(image.Width, image.Height); scaleFactor /= (int)multiplier; // Enum is effectively named constant with a value of 1, 2, or 3 var newWidth = (int)Math.Floor(image.Width / scaleFactor); var newHeight = (int)Math.Floor(image.Height / scaleFactor); using (var newBitmap = new Bitmap(newWidth, newHeight)) { using (var imageScaler = Graphics.FromImage(newBitmap)) { imageScaler.CompositingQuality = CompositingQuality.HighQuality; imageScaler.SmoothingMode = SmoothingMode.HighQuality; imageScaler.InterpolationMode = InterpolationMode.HighQualityBicubic; var imageRectangle = new Rectangle(0, 0, newWidth, newHeight); imageScaler.DrawImage(image, imageRectangle); newBitmap.Save(output, image.RawFormat); } } } } // Class definition for the class used in the method above public class TargetSize { /// /// The _width /// private readonly int _width; /// /// The _height /// private readonly int _height; /// /// Initializes a new instance of the class. /// /// The width. /// The height. public TargetSize(int width, int height) { _height = height; _width = width; } /// /// Calculates the scale factor. /// /// The width. /// The height. /// public decimal CalculateScaleFactor(int width, int height) { // Scale proportinately var heightScaleFactor = decimal.Divide(height, _height); var widthScaleFactor = decimal.Divide(width, _width); // Use the smaller of the two as the final scale factor so the image is never undersized. return widthScaleFactor > heightScaleFactor ? heightScaleFactor : widthScaleFactor; } } // NUnit integration test case I'm using to exercise the above code [Test] public void ResizeImage_Persistant_Single() { // Read the image from disk using (var fileStream = File.OpenRead(@"TestData\dog.jpg")) { using (var outputStream = new MemoryStream()) { // Call the resize image method detailed above. ResizeMultiplier.Medium casts to 2. _sut.ResizeImage(new TargetSize(200, 200), ResizeMultiplier.Medium, fileStream, outputStream); using (var newImage = Image.FromStream(outputStream)) { // Save the resized image to disk newImage.Save(@"TestData\ImageResizerTests.ResizeImage_Persistant_Single.jpg"); } } } }
例如这张图片:
是适当缩放但这个图像:
颠倒了。 值得一提的是,当图像在预览窗格中上传到此站点时,该图像似乎也是颠倒的。 那个事实(我很明显刚刚发现)强烈地让我觉得这个形象很有趣。 无论我的代码需要处理它。
Imgur “修复”了上面的文件(因为当我通过我的代码运行它时它现在不会旋转)所以我将它上传到Google云端硬盘 。 如果您右键单击图像(在FireFox中我没有测试过其他浏览器)并单击“ 将图像另存为...”,则图像不会随上面的代码一起旋转。 如果单击标题中的下载按钮,则图像会随我的代码一起旋转….这是狗图像的另一个副本 ,用我的代码翻转180度。 所有这一切都很奇怪,我不知道我做错了什么……
要明确我的目标是在不旋转图像的情况下调整图像大小。
根据评论进行编辑:
旋转/翻转的图像将以相同的方式一致地执行。 例如,这张狗图片将始终翻转180度。 有些照片会放在一边(旋转90度或270度)。 我已经validation了当dog图片翻转180度时, targetSize
, newHeight
, scaleFactor
, targetSize
(私有变量)和image.Height/image.Width
变量都是正数。
我不相信这是特定工具的神器。 我看到旋转通过; Windows资源管理器,Windows图像查看器,Macintosh图像查看器,FireFox等中的预览实际上我的公司的iOS开发人员在我们的应用程序中看到了这个问题。 我认为太多的工具都会看到它,因为它是一个观众问题。
感谢Chris Farmer 1和Mark Ransom 2的出色帮助,我能够回答我自己的问题。
核心问题是一些图像上的EXIF数据正在改变图像的方向。 当我调整图像大小时,所有EXIF数据都被删除了。 由于EXIF数据被剥离,观众不知道图像的方向应该不同。 这让我觉得缩放器代码正在旋转一些图像。 值得注意的是,在Windows资源管理器中右键单击图像时,此方向信息不会显示在详细信息视图中。 您需要在图像属性对象中搜索它或使用像这样的在线视图。
使用此处的数据 3我能够创建以下命名常量:
private const int OrientationKey = 0x0112; private const int NotSpecified = 0; private const int NormalOrientation = 1; private const int MirrorHorizontal = 2; private const int UpsideDown = 3; private const int MirrorVertical = 4; private const int MirrorHorizontalAndRotateRight = 5; private const int RotateLeft = 6; private const int MirorHorizontalAndRotateLeft = 7; private const int RotateRight = 8;
使用那些命名常量我扩展我的ResizeImage
方法读取:
public void ResizeImage(TargetSize targetSize, ResizeMultiplier multiplier, Stream input, Stream output) { using (var image = Image.FromStream(input)) { // Calculate the resize factor var scaleFactor = targetSize.CalculateScaleFactor(image.Width, image.Height); scaleFactor /= (int)multiplier; var newWidth = (int)Math.Floor(image.Width / scaleFactor); var newHeight = (int)Math.Floor(image.Height / scaleFactor); using (var newBitmap = new Bitmap(newWidth, newHeight)) { using (var imageScaler = Graphics.FromImage(newBitmap)) { imageScaler.CompositingQuality = CompositingQuality.HighQuality; imageScaler.SmoothingMode = SmoothingMode.HighQuality; imageScaler.InterpolationMode = InterpolationMode.HighQualityBicubic; var imageRectangle = new Rectangle(0, 0, newWidth, newHeight); imageScaler.DrawImage(image, imageRectangle); // Fix orientation if needed. if (image.PropertyIdList.Contains(OrientationKey)) { var orientation = (int)image.GetPropertyItem(OrientationKey).Value[0]; switch (orientation) { case NotSpecified: // Assume it is good. case NormalOrientation: // No rotation required. break; case MirrorHorizontal: newBitmap.RotateFlip(RotateFlipType.RotateNoneFlipX); break; case UpsideDown: newBitmap.RotateFlip(RotateFlipType.Rotate180FlipNone); break; case MirrorVertical: newBitmap.RotateFlip(RotateFlipType.Rotate180FlipX); break; case MirrorHorizontalAndRotateRight: newBitmap.RotateFlip(RotateFlipType.Rotate90FlipX); break; case RotateLeft: newBitmap.RotateFlip(RotateFlipType.Rotate90FlipNone); break; case MirorHorizontalAndRotateLeft: newBitmap.RotateFlip(RotateFlipType.Rotate270FlipX); break; case RotateRight: newBitmap.RotateFlip(RotateFlipType.Rotate270FlipNone); break; default: throw new NotImplementedException("An orientation of " + orientation + " isn't implemented."); } } newBitmap.Save(output, image.RawFormat); } } } }
一个善于观察的人会注意到,大多数附加代码都是从这个相关问题的答案中提取出来的 。
1 : 谁是对的钱,但我不明白他在开什么车。
2 : 谁向我展示了克里斯·法默试图说的话。
3 : 此处确认了 Orientation键值。
- 如何从Microsoft Azure Mobile Services中的表中读取数据并将其放入我的应用程序中?
- Visual Studio 2012 MVC构建错误:名称空间“System.Data.Entity”中不存在类型或命名空间名称“Infrastructure”
- 使用async / await设置Thread.CurrentPrincipal
- 在开发多租户asp.net MVC应用程序时要记住什么?
- entity framework可以在没有交集对象的情况下处理多对多关系吗?
- 如何将ListView按钮的绑定上下文设置为Xamarin Forms中父级的绑定上下文
- 在XP上使用Multicast的C#SocketException
- 生成Open XML Word文档后自动更新公式字段
- 在C#中将System.Web.UI.WebControls.Unit转换为int