使图片变为正方形

15

如何在C#中将图像重新采样为正方形,并用白色背景填充,最好不使用任何第三方库(仅使用.NET框架)?

谢谢!


1
您想将新采样的图像适配到一个白色画布的正方形中,使得图像保留其长宽比,还是将其拉伸以适应正方形(使白色画布有点不必要)? - JYelton
我想保持纵横比 - 不要拉伸 - Michael D.
@MichaelD. 那不是互相矛盾的吗?平方会改变宽高比。或者裁剪图像可以接受吗? - kenny
3个回答

29

这实际上可以相当容易地完成。

public static Image PadImage(Image originalImage)
{
    int largestDimension = Math.Max(originalImage.Height, originalImage.Width);
    Size squareSize = new Size(largestDimension, largestDimension);
    Bitmap squareImage = new Bitmap(squareSize.Width, squareSize.Height);
    using (Graphics graphics = Graphics.FromImage(squareImage))
    {
        graphics.FillRectangle(Brushes.White, 0, 0, squareSize.Width, squareSize.Height);
        graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
        graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
        graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

        graphics.DrawImage(originalImage, (squareSize.Width / 2) - (originalImage.Width / 2), (squareSize.Height / 2) - (originalImage.Height / 2), originalImage.Width, originalImage.Height);
    }
    return squareImage;
}

我知道这是一篇旧帖子,但它仍然很有用。我实际上使用了Math.Min来裁剪我的图像以获得缩略图。完美地工作! - AntLaC
如果将所有10个高度和宽度转换为整数,则此方法可行,但由于Size和Image值是双精度浮点数,因此需要进行转换。 - Kasper

2
尝试使用这种方法。最后一个参数是一个开关,用于确定是否要拉伸图片以适应画布。如果为false,则图像位于新的白色画布中心。您可以根据需要传递正方形或非正方形大小。
    public static Bitmap ResizeBitmapOnWhiteCanvas(Bitmap bmpOriginal, Size szTarget, bool Stretch)
    {
        Bitmap result = new Bitmap(szTarget.Width, szTarget.Height);
        using (Graphics g = Graphics.FromImage((Image)result))
        {
            g.InterpolationMode = InterpolationMode.NearestNeighbor;
            g.FillRectangle(Brushes.White, new Rectangle(0, 0, szTarget.Width, szTarget.Height));
            if (Stretch)
            {
                g.DrawImage(bmpOriginal, 0, 0, szTarget.Width, szTarget.Height); // fills the square (stretch)
            }
            else
            {
                float OriginalAR = bmpOriginal.Width / bmpOriginal.Height;
                float TargetAR = szTarget.Width / szTarget.Height;
                if (OriginalAR >= TargetAR)
                {
                    // Original is wider than target
                    float X = 0F;
                    float Y = ((float)szTarget.Height / 2F) - ((float)szTarget.Width / (float)bmpOriginal.Width * (float)bmpOriginal.Height) / 2F;
                    float Width = szTarget.Width;
                    float Height = (float)szTarget.Width / (float)bmpOriginal.Width * (float)bmpOriginal.Height;
                    g.DrawImage(bmpOriginal, X, Y, Width, Height);
                }
                else
                {
                    // Original is narrower than target
                    float X = ((float)szTarget.Width / 2F) - ((float)szTarget.Height / (float)bmpOriginal.Height * (float)bmpOriginal.Width) / 2F;
                    float Y = 0F;
                    float Width = (float)szTarget.Height / (float)bmpOriginal.Height * (float)bmpOriginal.Width;
                    float Height = szTarget.Height;
                    g.DrawImage(bmpOriginal, X, Y, Width, Height);
                }
            }
        }
        return result;
    }

1

您没有说明您希望如何填充。假设您希望图像居中,图像文件名为imageFileName,所需输出文件名为newFileName:

        Bitmap orig = new Bitmap(imageFileName);
        int dim = Math.Max(orig.Width, orig.Height);
        Bitmap dest;
        using (Graphics origG = Graphics.FromImage(orig))
        {
            dest = new Bitmap(dim, dim, origG);
        }
        using (Graphics g = Graphics.FromImage(dest))
        {
            Pen white = new Pen(Color.White, 22);
            g.FillRectangle(new SolidBrush(Color.White), 0, 0, dim, dim);
            g.DrawImage(orig, new Point((dim - orig.Width) / 2, (dim - orig.Height) / 2));
        }
        dest.Save(newFileName);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接