将图像缩放到1600px X 700像素

时间:2012-12-21 08:48:40

标签: c# image

当用户上传任何图片时,我们可以将其缩放到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;
        }

如果你查看下面的评论,他们说不可能在不丢失宽高比的情况下存档它,但是如果我看到来自airbnb的HERO图像,他们的图像是1600 X 700 ......

所以我觉得它有点可能,但我不知道如何实现它......

4 个答案:

答案 0 :(得分: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,可能会因图像垂直“挤压”而扭曲图像。
  3. 代码中的另一个问题是四舍五入问题。

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

    简单地切断小数位。即使计算结果为699.9,destWidth也是699。

    您可能希望使用Math.Round,而不是预期的699.9到700。

答案 1 :(得分:1)

嗯,实际上是的!在这个世界上几乎没有什么是不可能的。只是尝试搜索有关“seam carving”的信息。对不起,这里没有代码,因为我对这些算法并不熟悉。

答案 2 :(得分:0)

我已经通过几种方式调整了你的方法:

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

    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;
    }
    

答案 3 :(得分:-1)

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

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;
}