Reduce redundant code while working with image (delegate application)?
I'm working on a task that includes image processing. I've found out, that I'm repeating one code over and over (DRY alert) and I'm just curious, whether there is a way to avoid it.
The code is :
for (int x = 0; x < image.Width; x++)
{
for (int y = 0; y < image.Height; y++)
开发者_如何学C {
byte pixelValue = Convert.ToByte(Byte.MaxValue * image.GetPixel(x, y).GetBrightness());
//Do something with pixelValue
}
}
The variety of tasks is wide, once I'm creating histogram, then I'm thresholding the image etc.... I feel there might be some solution using delegates, but I only have limited experience with them and clearly this is not the most important to think of.
Can you propose a solution in .NET Framework 2.0 as well?
Thanks
I dont know about 2.0 but in 4.0 it would probably be something along the lines of
public void VisitPixels(Image image, Action<int,int,Pixel> func){
for (int x = 0; x < image.Width; x++)
{
for (int y = 0; y < image.Height; y++)
{
func(x,y,image.GetPixel(x,y));
}
}
}
If you want a return value it can get a bit more tricky but you can perhaps think of it like either a Map
or a Fold
Map
Pseudo:
public T[][] MapPixels<T>(Image image, Func<int,int,Pixel,T> func){
var ret = new T[image.Width][image.Height];
for (int x = 0; x < image.Width; x++)
{
for (int y = 0; y < image.Height; y++)
{
ret[x][y] = func(x,y,image.GetPixel(x,y)));
}
}
return ret;
}
Fold
public T FoldLPixels<T>(Image image, Func<T,Pixel,T> func, T acc){
var ret = acc;
for (int x = 0; x < image.Width; x++)
{
for (int y = 0; y < image.Height; y++)
{
ret = func(ret,image.GetPixel(x,y));
}
}
return ret;
}
You could then for example get an average Brightness like:
var avgBright = FoldLPixels(image,
(a,b)=>a+b.GetBrightness(),
0) / (image.Width+image.Height);
You could do it like this:
public static void ProcessPixelValues(Image image, Action<int, int, byte> processPixelValue)
{
for (int x = 0; x < image.Width; x++)
{
for (int y = 0; y < image.Height; y++)
{
byte pixelValue = Convert.ToByte(Byte.MaxValue * image.GetPixel(x, y).GetBrightness());
processPixelValue(x, y, pixelValue);
}
}
}
public static void PrintPixelValuesOfImage(Image image)
{
Action<int, int, byte> processPixelValue =
(x, y, pixelValue) => Console.WriteLine("The pixel value of [{0},{1}] is {2}", x, y, pixelValue);
ProcessPixelValues(image, processPixelValue);
}
C# 2.0 Code
public delegate void ProcessPixelValueCallback(int x, int y, byte pixelValue);
public static void ProcessPixelValues(Image image, ProcessPixelValueCallback processPixelValue)
{
for (int x = 0; x < image.Width; x++)
{
for (int y = 0; y < image.Height; y++)
{
byte pixelValue = Convert.ToByte(Byte.MaxValue * image.GetPixel(x, y).GetBrightness());
processPixelValue(x, y, pixelValue);
}
}
}
public static void PrintPixelValuesOfImage(Image image)
{
ProcessPixelValueCallback processPixelValue = delegate(int x, int y, byte pixelValue)
{
Console.WriteLine("The pixel value of [{0},{1}] is {2}", x, y, pixelValue);
};
ProcessPixelValues(image, processPixelValue);
}
精彩评论