Crop/Remove Unwanted Space at the edges of image

前端 未结 2 1180
野性不改
野性不改 2020-12-23 18:01

I have search a lot to remove the unwanted space but could not found. I only found links which can used to remove black and white background space. But my background images

2条回答
  •  情书的邮戳
    2020-12-23 18:45

    Here's my solution for your question :

    I have declared a method which gets the Original Image then It looks for the background Color by checking the corners of the provided Image , if at least 3 corners have similar Color (10% offset at most) then we've found the background color then It tries to find the bounds of those shapes in the Image which of course have different color than Background Color

    after Finding the Bounds The Function Crops the Image and Return the new Cropped Area as a new Bitmap !

    This is the Demo File : Download

    Complete Solution : Download

    Here's the results for :

    Image 1 :

    enter image description here

    Image 2 :

    enter image description here

    Image 3 :

    enter image description here

    here's the Function inside ImageProcessingTools class Simplified,

    public class ImageHelper
    {
        #region CropUnwantedBackground
        public static Bitmap CropUnwantedBackground(Bitmap bmp)
        {
            var backColor = GetMatchedBackColor(bmp);
            if (backColor.HasValue)
            {
                var bounds = GetImageBounds(bmp, backColor);
                var diffX = bounds[1].X - bounds[0].X + 1;
                var diffY = bounds[1].Y - bounds[0].Y + 1;
                var croppedBmp = new Bitmap(diffX, diffY);
                var g = Graphics.FromImage(croppedBmp);
                var destRect = new Rectangle(0, 0, croppedBmp.Width, croppedBmp.Height);
                var srcRect = new Rectangle(bounds[0].X, bounds[0].Y, diffX, diffY);
                g.DrawImage(bmp, destRect, srcRect, GraphicsUnit.Pixel);
                bmp.Dispose();
                return croppedBmp;
            }
            else
            {
                bmp.Dispose();
                return null;
            }
        }
        #endregion
    
        #region Private Methods
    
        #region GetImageBounds
        private static Point[] GetImageBounds(Bitmap bmp, Color? backColor)
        {
            //--------------------------------------------------------------------
            // Finding the Bounds of Crop Area bu using Unsafe Code and Image Proccesing
            Color c;
            int width = bmp.Width, height = bmp.Height;
            bool upperLeftPointFounded = false;
            var bounds = new Point[2];
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    c = bmp.GetPixel(x, y);
                    bool sameAsBackColor = ((c.R <= backColor.Value.R * 1.1 && c.R >= backColor.Value.R * 0.9) &&
                                            (c.G <= backColor.Value.G * 1.1 && c.G >= backColor.Value.G * 0.9) &&
                                            (c.B <= backColor.Value.B * 1.1 && c.B >= backColor.Value.B * 0.9));
                    if (!sameAsBackColor)
                    {
                        if (!upperLeftPointFounded)
                        {
                            bounds[0] = new Point(x, y);
                            bounds[1] = new Point(x, y);
                            upperLeftPointFounded = true;
                        }
                        else
                        {
                            if (x > bounds[1].X)
                                bounds[1].X = x;
                            else if (x < bounds[0].X)
                                bounds[0].X = x;
                            if (y >= bounds[1].Y)
                                bounds[1].Y = y;
                        }
                    }
                }
            }
            return bounds;
        } 
        #endregion
    
        #region GetMatchedBackColor
        private static Color? GetMatchedBackColor(Bitmap bmp)
        {
            // Getting The Background Color by checking Corners of Original Image
            var corners = new Point[]{
                new Point(0, 0),
                new Point(0, bmp.Height - 1),
                new Point(bmp.Width - 1, 0),
                new Point(bmp.Width - 1, bmp.Height - 1)
            }; // four corners (Top, Left), (Top, Right), (Bottom, Left), (Bottom, Right)
            for (int i = 0; i < 4; i++)
            {
                var cornerMatched = 0;
                var backColor = bmp.GetPixel(corners[i].X, corners[i].Y);
                for (int j = 0; j < 4; j++)
                {
                    var cornerColor = bmp.GetPixel(corners[j].X, corners[j].Y);// Check RGB with some offset
                    if ((cornerColor.R <= backColor.R * 1.1 && cornerColor.R >= backColor.R * 0.9) &&
                        (cornerColor.G <= backColor.G * 1.1 && cornerColor.G >= backColor.G * 0.9) &&
                        (cornerColor.B <= backColor.B * 1.1 && cornerColor.B >= backColor.B * 0.9))
                    {
                        cornerMatched++;
                    }
                }
                if (cornerMatched > 2)
                {
                    return backColor;
                }
            }
            return null;
        }  
        #endregion
        
        #endregion
    }
    

    and here is a simple one usage in ASP.NET,

    if (IsPostBack && Request.Files.Count > 0)
    {
        var file = Request.Files[0];
        var bmp = new Bitmap(file.InputStream);
        var croppedBmp = ImageHelper.CropUnwantedBackground(bmp);
        Response.ContentType = file.ContentType;
        croppedBmp.Save(Response.OutputStream, ImageFormat.Jpeg);
        Response.End();
    }
    

    And Finally I should mention that , these Fantastic Tutorials have Helped me a lot in Image Processing :

    Image Processing for Dummies with C# and GDI+

    Image Processing using C#

    Hope it Helps :)

提交回复
热议问题