简而言之,以下代码的目的是根据目标大小和乘数(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
{
/// <summary>
/// The _width
/// </summary>
private readonly int _width;
/// <summary>
/// The _height
/// </summary>
private readonly int _height;
/// <summary>
/// Initializes a new instance of the <see cref="TargetSize"/> class.
/// </summary>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
public TargetSize(int width, int height)
{
_height = height;
_width = width;
}
/// <summary>
/// Calculates the scale factor.
/// </summary>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
/// <returns></returns>
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 Drive 。如果您右键单击图像(在 FireFox 中我没有测试过其他浏览器)并单击 Save Image As... 那么图像不会随着我上面的代码旋转。如果您单击标题中的下载按钮,那么图像会随着我的代码旋转……这里是 another copy用我的代码翻转 180 度的狗图像。这一切都非常奇怪,我不知道我做错了什么......
需要说明的是,我的目标是在不旋转图像的情况下调整图像大小。 根据评论进行编辑: 旋转/翻转的图像将以相同的方式一致地旋转/翻转。例如,这张狗图片将始终翻转 180 度。有些图片会侧放(旋转 90 或 270 度)。我已经验证了 我认为这不是特定工具的产物。我看到旋转通过; Windows Explorer、Windows Image Viewer、库存 Macintosh 图像查看器、FireFox 等中的预览。实际上,我公司的一位 iOS 开发人员在我们的应用程序中看到了这个问题,引起了我的注意。我认为有太多工具将其视为查看器问题。
newWidth , newHeight , scaleFactor , targetSize (私有(private)变量)和image.Height/image.Width当狗图片翻转 180 度时变量都是正的。
最佳答案
感谢 Chris Farmer 的大力帮助1 和 Mark Ransom 2 我能够回答我自己的问题。
核心问题是某些图像上的 EXIF 数据改变了图像的方向。当我调整图像大小时,所有 EXIF 数据都被剥离了。由于 EXIF 数据被剥离,观看者不知道图像的方向应该不同。这使我认为调整大小的代码正在旋转一些图像。值得注意的是,当您在 Windows 资源管理器中右键单击图像时,此方向信息不会显示在详细信息 View 中。您需要在图像属性对象中搜索它或使用像 this one 这样的在线 View 。 .
使用 data from here 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);
}
}
}
}
细心的人会注意到大部分附加代码都被提取了 from this answer一个相关的问题。
1:谁是对的,但我不明白他的目的。
2:谁向我展示了 Chris Farmer 想说的话。
3:Orientation 键值为 confirmed here .
关于c# - 调整大小时,某些图像正在旋转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33310562/
我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,
我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
我有带有Logo图像的公司模型has_attached_file:logo我用他们的Logo创建了许多公司。现在,我需要添加新样式has_attached_file:logo,:styles=>{:small=>"30x15>",:medium=>"155x85>"}我是否应该重新上传所有旧数据以重新生成新样式?我不这么认为……或者有什么rake任务可以重新生成样式吗? 最佳答案 参见Thumbnail-Generation.如果rake任务不适合你,你应该能够在控制台中使用一个片段来调用重新处理!关于相关公司
点向量坐标矩阵的几何意义介绍旋转矩阵的几何含义之前,先介绍一下点向量坐标矩阵的几何含义点:在一维空间下就是一个标量,如同一条直线上,以任意某一个位置为0点,以一定的尺度间隔为1,2,3...,相反方向为-1,-2,-3...;如此就形成了一维坐标系,这时候任何一个点都可以用一个数值表示,如点p1=5,即即从原点出发沿着x轴正方向移动5个尺度;点p2=-3,负方向移动3个尺度; 在一维坐标系上过原点做垂直于一维坐标系的直线,则形成了二维坐标系,此时描述一个点需要两个数值来表示点p3=(3,2),即从原点出发沿着x轴正方向移动3个尺度,在此基础上沿着y轴正方向移动两个尺度的位置就是点p3。
Unity自动旋转动画1.开门需要门把手先动,门再动2.关门需要门先动,门把手再动3.中途播放过程中不可以再次进行操作觉得太复杂?查看我的文章开关门简易进阶版效果:如果这个门可以直接打开的话,就不需要放置"门把手"如果门把手还有钥匙需要旋转,那就可以把钥匙放在门把手的"门把手",理论上是可以无限套娃的可调整参数有:角度,反向,轴向,速度运行时点击Test进行测试自己写的代码比较垃圾,命名与结构比较拉,高手轻点喷,新手有类似的需求可以拿去做参考上代码usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;u
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
我正在尝试使用Ruby2.0.0和Rails4.0.0提供的API从imgur中提取图像。我已尝试按照Ruby2.0.0文档中列出的各种方式构建http请求,但均无济于事。代码如下:require'net/http'require'net/https'defimgurheaders={"Authorization"=>"Client-ID"+my_client_id}path="/3/gallery/image/#{img_id}.json"uri=URI("https://api.imgur.com"+path)request,data=Net::HTTP::Get.new(path
2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p