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

标签 c# asp.net .net image-processing gdi+

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

enter image description here

Image1

enter image description here

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

enter image description here enter image description here enter image description here

最佳答案

这是我对你的问题的解决方案:

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

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

这是演示文件:Download

完整的解决方案:Download

这是 :

的结果

图片 1:

enter image description here

图片 2:

enter image description here

图 3:

enter image description here

这是 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);
            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
}

这是 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();
}

最后我要提一下,这些很棒的教程在图像处理方面对我帮助很大:

Image Processing for Dummies with C# and GDI+

Image Processing using C#

希望对您有所帮助:)

关于c# - 裁剪/删除图像边缘不需要的空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13548962/

相关文章:

C# 方法慢 100 倍,三个返回比两个?

c# - 将多维特征分类为两组的神经网络示例

c# - 如何将javascript日期存储到sql server中?

c# - 等同于 C# 中的协议(protocol)和委托(delegate)

c# - 等待一个线程在 C# 中实际启动

c# - 从 silverlight 富文本框中提取纯文本 - LINQ to XML

c# - 将数据从 ASP.Net 4.5 发布到 ASP.Net 2.0 Web 应用程序时出错

javascript - 如何在asp服务器中保存更新完整日历事件

c# - 生成随机颜色的问题 - asp.net 和 c#

c# - 枚举命名约定 - 复数