C# ImageResizer为图像生成错误的宽度

C# ImageResizer为图像生成错误的宽度,c#,imageresizer,C#,Imageresizer,我允许用户上传最小宽度为400px的横幅。该图像将获得1110px的宽度。 我尝试上传以下尺寸的图像:960x390、410x410、784x250。 当我上传784x250时,图像的大小与784x250相同,而不是宽度1110px 我用这个: int Height; using (var Bmp = new Bitmap(str)) { if (Bmp.Width < 400) {

我允许用户上传最小宽度为400px的横幅。该图像将获得1110px的宽度。 我尝试上传以下尺寸的图像:960x390、410x410、784x250。 当我上传784x250时,图像的大小与784x250相同,而不是宽度1110px

我用这个:

        int Height;
        using (var Bmp = new Bitmap(str))
        {
            if (Bmp.Width < 400)
            {
                throw;
            }
            if (Bmp.Height < 150)
            {
                throw;
            }
            Height = Bmp.Height;
        }

        if (Height > 300)
        {
            Height = 300;
        }

        str.Position = 0;
        var ImageData = str.StreamToByteArray();

        var Settings = "width=1110;height="+ Height + ";format=jpg;mode=crop;"

        var Setting = new ResizeSettings(Settings);
        using (var Out = new MemoryStream())
        {
            using (var In = new MemoryStream(ImageData))
            {
                In.Seek(0, SeekOrigin.Begin);

                var I = new ImageJob(In, Out, Setting)
                {
                    CreateParentDirectory = false
                };
                I.Build();
            }

            Out.Position = 0;

            // Upload to blob
        }
int高度;
使用(var Bmp=新位图(str))
{
如果(Bmp.Width<400)
{
投掷;
}
如果(Bmp.Height<150)
{
投掷;
}
高度=Bmp.高度;
}
如果(高度>300)
{
高度=300;
}
str.Position=0;
var ImageData=str.StreamToByteArray();
var Settings=“width=1110;height=“+height+”;format=jpg;mode=crop
var设置=新的大小设置(设置);
使用(var Out=new MemoryStream())
{
使用(var In=新内存流(ImageData))
{
In.Seek(0,SeekOrigin.Begin);
var I=新图像作业(输入、输出、设置)
{
CreateParentDirectory=false
};
I.构建();
}
位置=0;
//上传到blob
}
(str包含带有图像的流)

我希望图像是1110px宽,最大300px高。
有什么问题?

您测试的其他尺寸都有
Bmp.Height>300
,这意味着图像需要裁剪。
但是,当使用尺寸为784x250的图像时,不需要裁剪图像。因此,您永远不会重新调整图像的大小

假设您希望保持图像按比例正确,则应首先重新调整图像大小以匹配所需的宽度,然后根据需要裁剪超出的高度

var image = new Bitmap(str);

var ratio = (double)1110 / image.Width;

var newWidth = (int)(image.Width * ratio);
var newHeight = (int)(image.Height * ratio);

var newImage = new Bitmap(newWidth, newHeight);

Graphics.FromImage(newImage).DrawImage(image, 0, 0, newWidth, newHeight);
var bmp = new Bitmap(newImage);

if(bmp.Height > 300){
//Resize again using crop, like you did in your original code.
}

除非您通过
scale=both
scale=canvas
明确要求,否则ImageResizer不会提升图像的比例。放大通常是不需要的

此外,您还可以将流直接传递给ImageJob,并显著简化代码

str.Seek(0, SeekOrigin.Begin);
var Out = new MemoryStream(8096);
new ImageJob(str, Out, new Instructions("width=1110;height="+ Height + ";format=jpg;mode=crop;scale=both")).Build();
Out.Seek(0, SeekOrigin.Begin);

我将冒昧猜测这就是罪魁祸首:“mode=crop;”请记住,位图和图形实例不会被垃圾收集,因为它们在.NET GC中显示为1kb(而不是90mb)。因此,如果连续调用几十次此代码,将使服务器崩溃。此外,DrawImage使用进程范围的锁(与ImageResizer的FastScaling引擎不同),因此如果存在并发请求,那么这些大内存块将被保留非常长的时间。