裁剪/删除图像边缘的不需要的空间

use*_*567 13 .net c# asp.net gdi+ image-processing

我搜索了很多,以删除不需要的空间,但无法找到.我只找到了可用于删除黑白背景空间的链接.但我的背景图片可以是任何东西.那么,如果我有这些图像,

在此输入图像描述

此搜索

在此输入图像描述

如何提取我需要的图像部分.例如,

在此输入图像描述 在此输入图像描述 在此输入图像描述

Meh*_*ran 23

这是我的问题解决方案:

我已经声明了一个获取原始图像的方法然后它通过检查提供的图像的角来查找背景颜色,如果至少3个角有相似的颜色(最多10%偏移),那么我们找到了背景颜色然后它试图在图像中找到那些形状的边界,当然这些形状具有与背景颜色不同的颜色

查找边界后,函数裁剪图像并将新的裁剪区域作为新的位图返回!

这是演示文件:下载

完整解决方案:下载

以下是结果:

Image 1 :

在此输入图像描述

Image 2 :

在此输入图像描述

Image 3 :

在此输入图像描述

这里是ImageProcessingTools简化的类里面的函数,

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);
            return croppedBmp;
        }
        else
        {
            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
}
Run Code Online (Sandbox Code Playgroud)

这是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();
}
Run Code Online (Sandbox Code Playgroud)

最后我要提一下,这些神奇的教程在图像处理方面给了我很多帮助:

C#和GDI +对虚拟人物的图像处理

使用C#进行图像处理

希望能帮助到你 :)

  • 我已经简化了你的代码了.见上面的编辑. (2认同)