Linq而不是两个循环获得像素颜色并从图像指向

时间:2011-10-13 13:17:27

标签: c# linq image-processing pixel

如何使用linq列出图像中的所有像素并对其进行处理? 例如,我们有:

 for (int i = 0; i < this.bitmap.Width; i++)
            {
                for (int j = 0; j < this.bitmap.Height; j++)
                {
                    bitmap.SetPixel(x, y, Color.FromArgb(1, 1, 1));
                }
            }

这里我不需要列表像素,因为我立即使用for循环工作。 但是我不确定我是否可以像这样使用linq处理图像。 我知道linq获取数据所以,我想从点获取像素,并以某种方式存储该像素的coorinates和颜色数据。我需要那个,因为我怎么能做出门槛?

我尝试使用struct但是在页面http://social.msdn.microsoft.com/Forums/is/linqtosql/thread/02154de8-ef32-4420-a3f6-e4e473df66ce上他们说linq不能用于struct。

也许我应该使用列表,但是当我写作时 List<Point, Color> list我收到了错误。所以我真的不知道该怎么做..

所有的事情都是要在该文本下优化我的功能。我在书中读到了“c#中的effectice编程”,使用查询语法比for循环更具可读性。

这是我的代码,我真的向您寻求帮助,使其更具可读性。

PS。如果我的指定不好,请更正主题,抱歉。

  

private void ThreshGrayTails()           {

        this.tempBitmap = new Bitmap(this.bitmap);

        for (int i = 0; i < this.bitmap.Width; i++)
        {
            for (int j = 0; j < this.bitmap.Height; j++)
            {
                SetTempPixelInt(i, 0, j, 0, this.tempBitmap);

                if (this.tempPixelInt == 252 && (j + 2) < this.bitmap.Height && (j - 2) > 0)
                {
                    SetTempPixelInt(i, 0, j, -1, this.bitmap);

                    //if pixel above has value 252
                    if (this.tempPixelInt == 252)
                    {
                        SetTempPixelInt(i, 0, j, -2, this.bitmap);

                        //if pixel above has value 159
                        if (this.tempPixelInt == 159)
                        {
                            SetTempPixelInt(i, 0, j, +1, this.bitmap);

                            //if pixel under has value 0 or 172
                            if (this.tempPixelInt == 0 || this.tempPixelInt == 172)
                            {
                                this.tempBitmap.SetPixel(i, j, Color.FromArgb(255, 255, 255));
                                this.tempBitmap.SetPixel(i - 1, j, Color.FromArgb(255, 255, 255));
                                this.tempBitmap.SetPixel(i - 2, j, Color.FromArgb(255, 255, 255));
                            }
                        }
                    }

                }

                //if current pixel doesnt contain value in that list, turn it on black
                if (!colorsToThreshold.Contains(this.tempBitmap.GetPixel(i, j).R))
                {
                    Color newcolor = Color.FromArgb(0, 0, 0);
                    this.tempBitmap.SetPixel(i, j, newcolor);
                }
                //if current pixel contain value in that list, turn it on white
                else
                {
                    Color newcolor = Color.FromArgb(255, 255, 255);
                    this.tempBitmap.SetPixel(i, j, newcolor);
                }

            }

        }
        this.bitmap = new Bitmap(this.tempBitmap);
        SaveImage("thresholded.bmp", this.bitmap);
    }

    private void SetTempPixelInt(int i, int pi, int j, int pj, Bitmap bitmap)
    {
        Color currentColor = bitmap.GetPixel(i + pi, j + pj);
        this.tempPixelInt = (int)(currentColor.R);
    }

2 个答案:

答案 0 :(得分:1)

当您尝试改进代码时,我认为您正在寻找错误的方向。

图像中的像素无法作为集合访问,因此您无法使用开箱即用的LINQ。您必须创建一些可以将像素作为集合的东西,以便在查询中使用它们。您可以使用Range方法创建一个可以访问像素的查询,但这只是一种缓慢而复杂的方式来执行您在循环中已经执行的操作。

您阅读LINQ不适用于结构的文章适用于您没有使用的LINQ to SQL。但是,使用结构体并不会使LINQ更容易使用它。

答案 1 :(得分:1)

  

所有的事情都是要在该文本下优化我的功能

如果您想提高性能,最好的解决方案是使用不安全的代码直接访问内存中的像素。您应该在Bitmap上使用LockBits()方法来实现此目的。可以在此处找到c#中快速图像处理的一些示例:http://www.vcskicks.com/fast-image-processing.php

LINQ实际上不是解决此类问题的方法。