C# 调整大小时,某些图像正在旋转
简而言之,下面代码的目的是根据目标大小和乘数(1x、2x、3x)调整图像大小。这工作正常,除了一些原因,我还没有确定一些图像正在旋转C# 调整大小时,某些图像正在旋转,c#,image,image-processing,image-rotation,C#,Image,Image Processing,Image Rotation,简而言之,下面代码的目的是根据目标大小和乘数(1x、2x、3x)调整图像大小。这工作正常,除了一些原因,我还没有确定一些图像正在旋转 public void ResizeImage(TargetSize TargetSize,ResizeMultiplier乘数,流输入,流输出) { 使用(var image=image.FromStream(输入)) { //计算调整大小因子 var scaleFactor=targetSize.CalculateScaleFactor(image.Width
public void ResizeImage(TargetSize TargetSize,ResizeMultiplier乘数,流输入,流输出)
{
使用(var image=image.FromStream(输入))
{
//计算调整大小因子
var scaleFactor=targetSize.CalculateScaleFactor(image.Width,image.Height);
scaleFactor/=(int)乘数;//枚举有效地命名为常量,其值为1、2或3
var newWidth=(int)Math.Floor(image.Width/scaleFactor);
var newHeight=(int)Math.Floor(image.Height/scaleFactor);
使用(var newBitmap=新位图(newWidth、newHeight))
{
使用(var imageScaler=Graphics.FromImage(newBitmap))
{
imageScaler.CompositingQuality=CompositingQuality.HighQuality;
imageScaler.SmoothingMode=SmoothingMode.HighQuality;
imageScaler.InterpolationMode=InterpolationMode.HighQualityBicubic;
var imageRectangle=新矩形(0,0,newWidth,newHeight);
imageScaler.DrawImage(图像,图像矩形);
保存(输出,image.RawFormat);
}
}
}
}
//上述方法中使用的类的类定义
公共类目标大小
{
///
///宽度
///
私有只读整数宽度;
///
///高度
///
专用只读int_高度;
///
///初始化类的新实例。
///
///宽度。
///高度。
公共目标大小(整数宽度、整数高度)
{
_高度=高度;
_宽度=宽度;
}
///
///计算比例因子。
///
///宽度。
///高度。
///
公共十进制计算比例因子(整数宽度、整数高度)
{
//按比例缩放
var heightScaleFactor=十进制除法(高度,_高度);
var widthScaleFactor=decimal.Divide(宽度,_宽度);
//使用两者中较小的一个作为最终比例因子,这样图像就不会过小。
返回widthScaleFactor>heightScaleFactor?heightScaleFactor:widthScaleFactor;
}
}
//我用来练习上述代码的NUnit集成测试用例
[测试]
public void ResizeImage\u Persistant\u Single()
{
//从磁盘读取映像
使用(var fileStream=File.OpenRead(@“TestData\dog.jpg”))
{
使用(var outputStream=new MemoryStream())
{
//调用上面详述的ResizeImage方法。ResizeMultiplier.Medium强制转换为2。
_sut.ResizeImage(新TargetSize(200200)、ResizeMultiplier.Medium、fileStream、outputStream);
使用(var newImage=Image.FromStream(outputStream))
{
//将调整大小的图像保存到磁盘
newImage.Save(@“TestData\ImageResizerTests.ResizeImage_Persistant_Single.jpg”);
}
}
}
}
例如,此图像:
已适当缩放,但此图像:
被翻转过来。值得一提的是,在预览窗格中将图像上载到此站点时,图像似乎也颠倒了。这一事实(显然是我刚刚发现的)强烈地让我觉得这张照片很有趣。不管怎样,我的代码需要处理它
Imgur“修复”了上面的文件(因为在我运行代码时,它现在不会旋转),所以我将其上载到了。如果您右键单击图像(在FireFox中,我没有测试过其他浏览器),然后单击“将图像另存为…”。。。然后图像不会随着上面的代码旋转。如果您单击标题中的下载按钮,则图像将与我的代码一起旋转。。。。这是一个狗的形象,翻转180度与我的代码。所有这些都很奇怪,我不知道我做错了什么
为了清楚,我的目标是在不旋转图像的情况下调整图像大小
根据评论进行编辑: 旋转/翻转的图像将以相同的方式持续旋转/翻转。例如,此狗图片将始终翻转180度。有些图片将侧放(旋转90或270度)。我已经验证了当狗狗图片翻转180度时,
newWidth
、newHeight
、scaleFactor
、targetSize
(私有变量)和image.Height/image.Width
变量都是正值
我不相信这是特定工具的产物。我看到旋转通过;Windows资源管理器、Windows图像查看器、Macintosh股票图像查看器、FireFox等中的预览。实际上,我公司的一位iOS开发人员在我们的应用程序中看到了这个问题,引起了我的注意。我认为有太多的工具看到了这一点,这将成为一个查看器问题。多亏了1和2的出色帮助,我才能够回答自己的问题 核心问题是一些图像上的EXIF数据改变了图像的方向。当我调整图像大小时,所有EXIF数据都被剥离。由于EXIF数据被剥离,观众不知道图像的方向应该不同。这让我觉得调整大小的代码正在旋转一些图像。值得注意的是,在Windows资源管理器中右键单击图像时,此方向信息不会显示在“详细信息”视图中。您需要在图像属性对象中搜索它,或使用类似的联机视图 使用3,我能够创建以下命名常量: 使用这些命名常量,我将我的
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);
}
}
}
}
有观察力的人会注意到,大多数附加代码都被拉到了一个相关的问题上
他说:谁在钱的问题上是对的,但我不明白他是什么
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);
}
}
}
}