tags:

views:

139

answers:

3

Hi

How to resample an image to square, padding with white background in c# preferable without using any 3rd party libraries (.Net framework only)?

Thanks!

+1  A: 

Try using this method. The last argument is a switch for whether you want to stretch the image to fit. If false, the image is centered inside the new white canvas. You can pass a square or non-square size to it as needed.

    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;
    }
JYelton
+1  A: 

You don't say how you want it padded. Assuming you want the image centered, with the image file name in imageFileName and the desired output file name in 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);
Mark Nelson
+1  A: 

This can actually be done pretty easily.

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