在C#中删除JPEG工件

Arc*_*rus 5 c# gdi+ bitmap image-processing

我正在为一个母亲组织的俱乐部建立一个网站.我正在下载(leeching;))放在母组织的个人资料页面上的图像,以显示在我自己的页面上.但他们的网站有一个漂亮的白色背景,我的网站背景上有一个漂亮的灰色渐变.这不太匹配.所以我的想法是在将图像保存到我的服务器之前编辑它们.

我正在使用GDI +来增强我的图像,当我使用Bitmap的MakeTransparent方法时,它确实有效,它确实做了它应该做的事情,但我仍然有这些白色的jpeg工件.工件使图像变得如此糟糕,我最好不要使图像透明,只留下白色,但这在我自己的网站上真的很难看.当然,我总是可以在一个带有白色背景的漂亮边框上,但我宁愿将背景更改为透明.

所以我想知道是否以及如何在C#中删除一些简单的JPEG工件.有没有人曾经这样做过?

谢谢你的时间.

示例图片:

TB-5404

转换后的形象:

TB-5404转化

Cod*_*Tao 5

好吧,我尝试了一些远非完美的东西,但我认为它可能对其他人有用.

我得到了:

替代文字

遇到的问题:阴影远离'白色',很难自动转换它们,即使你做了阴影仍然会在图像本身.顶部眩光......毂的东西,也更接近白色和抗锯齿位.图像中有三到七个白点,它们没有连接到任何一个主角; 最后,边缘仍然有一点白色(可能可以通过调整代码摆脱它,但不能没有取下部分眩光顶部.

C#效率低下的代码:

    static void Main()
    {
        Bitmap bmp=new Bitmap("test.jpg");

        int width = bmp.Width;
        int height = bmp.Height;
        Dictionary<Point, int> currentLayer = new Dictionary<Point, int>();
        currentLayer[new Point(0, 0)] = 0;
        currentLayer[new Point(width - 1, height - 1)] = 0;
        while (currentLayer.Count != 0)
        {
            foreach (Point p in currentLayer.Keys)
                bmp.SetPixel(p.X, p.Y, Color.Black);
            Dictionary<Point, int> newLayer = new Dictionary<Point, int>();
            foreach (Point p in currentLayer.Keys)
                foreach (Point p1 in Neighbors(p, width, height))
                    if (Distance(bmp.GetPixel(p1.X, p1.Y), Color.White) < 40)
                        newLayer[p1] = 0;
            currentLayer = newLayer;
        }

        bmp.Save("test2.jpg");
    }

    static int Distance(Color c1, Color c2)
    {
        int dr = Math.Abs(c1.R - c2.R);
        int dg = Math.Abs(c1.G - c2.G);
        int db = Math.Abs(c1.B - c2.B);
        return Math.Max(Math.Max(dr, dg), db);
    }

    static List<Point> Neighbors(Point p, int maxX, int maxY)
    {
        List<Point> points=new List<Point>();
        if (p.X + 1 < maxX) points.Add(new Point(p.X + 1, p.Y));
        if (p.X - 1 >= 0) points.Add(new Point(p.X - 1, p.Y));
        if (p.Y + 1 < maxY) points.Add(new Point(p.X, p.Y + 1));
        if (p.Y - 1 >= 0) points.Add(new Point(p.X, p.Y - 1));
        return points;
    }
Run Code Online (Sandbox Code Playgroud)

代码以两点开始工作; 将它们设置为黑色,然后检查它们附近的邻居是否接近白色; 如果他们被添加到列表然后执行.最终它会耗尽白色像素来改变.

作为替代方案,您可能需要考虑重新设计网站以使用白色背景.