Уменьшить избыточный код при работе с изображением (делегировать приложение)? - PullRequest
1 голос
/ 23 марта 2011

Я работаю над задачей, которая включает в себя обработку изображений. Я обнаружил, что я повторяю один и тот же код снова и снова (СУХОЕ предупреждение), и мне просто любопытно, есть ли способ избежать этого.

Код:

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());
        //Do something with pixelValue
    }
}

Разнообразие задач велико, когда я создаю гистограмму, затем устанавливаю пороговое значение изображения и т. Д. .... Я чувствую, что может быть какое-то решение с использованием делегатов, но у меня ограниченный опыт работы с ними, и ясно не самое главное, о чем думать.

Можете ли вы предложить решение и в .NET Framework 2.0?

Спасибо

Ответы [ 2 ]

1 голос
/ 23 марта 2011

Я не знаю о 2.0, но в 4.0 это, вероятно, будет что-то вроде

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

Если вы хотите получить возвращаемое значение, оно может стать немного сложнее, но вы можете думать о нем каклибо Map, либо Fold

Карта

Псевдо:

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

Сгиб

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

Вы можете, например, получить среднюю Яркость, например:

var avgBright = FoldLPixels(image, 
                            (a,b)=>a+b.GetBrightness(),
                            0) / (image.Width+image.Height);
0 голосов
/ 23 марта 2011

Вы можете сделать это так:

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 Код

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