0

当用户上传任何图像时,我们可以将其缩放到 1600 X 700 吗?

我正在使用下面的代码来缩放 1996 X 1442 的图像,但它永远不会缩放到 1600 X 700。

有没有更好的方法或其他方法来实现它?

private static Image resizeImage(Image imgToResize, Size size)
        {
            int sourceWidth = imgToResize.Width;
            int sourceHeight = imgToResize.Height;

            float nPercent = 0;
            float nPercentW = 0;
            float nPercentH = 0;

            nPercentW = ((float)size.Width / (float)sourceWidth);
            nPercentH = ((float)size.Height / (float)sourceHeight);

            if (nPercentH < nPercentW)
                nPercent = nPercentH;
            else
                nPercent = nPercentW;

            int destWidth = (int)(sourceWidth * nPercent);
            int destHeight = (int)(sourceHeight * nPercent);

            Bitmap b = new Bitmap(destWidth, destHeight);
            Graphics g = Graphics.FromImage((Image)b);
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;

            g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
            g.Dispose();

            return (Image)b;
        }

如果您查看下面的评论,他们说如果不丢失宽高比就无法存档,但如果我看到 HERO 图像,airbnb他们有 1600 X 700 的图像......

所以我认为这是可能的,但我不知道如何实现它......

4

4 回答 4

2

当然不是,因为 1600 x 700 的纵横比 (0.4375) 与 1996 x 1442 (0.7724) 不同。你这样做的方式是缩放保持纵横比,所以你永远不会从 1996 x 1442 达到 1600 x 700。

你可以:

  1. 缩放图像,使较长的角为 1600 长,然后剪下尺寸为 1600 x 700 的相关部分(保持纵横比)。
  2. 将图像缩放到 1600 x 700,可能会在垂直“挤压”时扭曲图像。

代码中的另一个问题是舍入问题。

int destWidth = (int)...;
int destHeight = (int)...;

简单地去掉小数位。即使计算结果是 699.9,destWidth也会是 699。

您可能想Math.Round改用它,这将按预期将 699.9 舍入到 700。

于 2012-12-21T08:51:52.157 回答
1

嗯,其实是的!这个世界上几乎没有什么是不可能的。只是尝试搜索有关“缝雕”的信息。抱歉,这里没有代码,因为我对这些算法不太熟悉。

于 2012-12-21T08:59:37.827 回答
0

我在几个方面调整了你的方法:

  1. 它现在根据较大的比例进行缩放,而不是较小的比例,因此您最终将修剪图像上的位而不是留下白色(?)信箱。(这只是<vs >,所以很容易改变。)
  2. 对于应该相等的一侧,这可以确保它是相等的,而不是缩放和舍入,并希望你最终不会有一个像素差异。
  3. 如果纵横比不匹配,它会将绘制的图像居中,g因此您最终会得到等量的修剪左右或顶部和底部。(在不知道原始图像的比例是否正确的情况下,您必须以某种方式决定要修剪图像的哪些位。)

试一试,看看你是否喜欢结果。

private static Image resizeImage(Image imgToResize, Size size)
{
    int sourceWidth = imgToResize.Width;
    int sourceHeight = imgToResize.Height;

    double wRatio = (double)size.Width / sourceWidth;
    double hRatio = (double)size.Height / sourceHeight;

    int destWidth, destHeight;
    float top, left;

    if (wRatio > hRatio) // reverse for white bars rather than trimming
    {
        destWidth = size.Width;
        destHeight = (int)Math.Ceiling(sourceHeight * wRatio);
        left = 0;
        top = (destHeight - size.Height) / 2f;
    }
    else
    {
        destHeight = size.Height;
        destWidth = (int)Math.Ceiling(sourceWidth * hRatio);
        top = 0;
        left = (destWidth - size.Width) / 2f;
    }

    Bitmap b = new Bitmap(size.Width, size.Height);
    Graphics g = Graphics.FromImage((Image)b);
    g.InterpolationMode = InterpolationMode.HighQualityBicubic;

    g.DrawImage(imgToResize, left, top, destWidth, destHeight);
    g.Dispose();

    return (Image)b;
}
于 2012-12-21T08:54:30.570 回答
-1

此代码保留原始图像的纵横比。如果保留它不重要,那么您可以摆脱比率计算部分并直接创建一个具有提供大小的位图对象。

private static Image resizeImage(Image imgToResize, Size size)
{
    Bitmap b = new Bitmap(size.Width, size.Height);
    Graphics g = Graphics.FromImage((Image)b);
    g.InterpolationMode = InterpolationMode.HighQualityBicubic;

    g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
    g.Dispose();

    return (Image)b;
}
于 2012-12-21T08:55:52.613 回答