Search code examples
c#linqimage-processingpixel

Linq instead two loops get pixel color and point from image


How can i use linq to list all pixels from image and process on them? For example we have:

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

Here i do not need list pixels because i work immediately using meanwhile for loops. However i am not sure if i can process image with linq like that. I understand that linq gain data so, i would like to take pixel from point and somehow store coorinates and color data of that pixel. I need that because how would i be able then make threshold?

I tried to use struct but on page http://social.msdn.microsoft.com/Forums/is/linqtosql/thread/02154de8-ef32-4420-a3f6-e4e473df66ce they said that linq doesn't work with struct.

Maybe i should use list but when i wrote List<Point, Color> list i got error. So i really don't know how to do that..

The all thing is about to optimalize my function under that text. I read in book called "effectice programming in c#" that using query syntax would be more readable than for loops..

This is my code and i really ask you for a help how make it more readable code.

ps. please correct topic if it is not good specified by me, sorry.

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

Solution

  • The all thing is about to optimalize my function under that text

    If you want to improve performance the best solution for you would be to use unsafe code to access pixels directly in memory. You should use LockBits() method on Bitmap to achieve this. Some example of fast image processing in c# can be found here: http://www.vcskicks.com/fast-image-processing.php

    LINQ is really not a solution for such a problem.