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 syn开发者_如何学编程tax 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); }
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.
I think that you are looking in the wrong direction when you try to improve the code.
The pixels in the image is not accessible as a collection, so you can't use LINQ on them out of the box. You would have to create something that can give you the pixels as a collection in order to use them in a query. You can use the Range
method to create a query where you can access the pixels, but that would only be a slow and complicated way of doing what you are already doing in your loops.
The article where you read that LINQ doesn't work with structs applies to LINQ to SQL, which you are not using. However, using a struct would not really make it any easier to use LINQ for this.
精彩评论