2012-01-25 4 views
0

Что я пытаюсь сделать, это проверить строку или столбец изображения, и если он содержит все белые пиксели, то обрезайте эту строку или столбец. Я не уверен, почему, но когда я запускаю этот фрагмент кода, img.Width в TrimLeft равен 1, прежде чем вычесть 1 из него. Фактическая ширина изображения - 175. Я получаю исключение ArgumentException. У меня есть аналогичный метод для обрезки правой стороны, и это отлично работает.C# Проблемы с битмапом

class ImageHandler 
{ 

    public Bitmap img; 
    public List<int[]> pixels = new List<int[]>(); 

    public ImageHandler(String path) 
    { 
     img = new Bitmap(path); 
     GetPixels(); 
    } 

    public void TrimLeft() 
    { 
     while (CheckColIfWhite(0, 0)) 
     { 
      Rectangle cropBox = new Rectangle(1, 0, (img.Width-1), img.Height); 
      Bitmap cropdImg = CropImage(img, cropBox); 
      img = cropdImg; 
     } 
    } 

    public bool CheckColIfWhite(int colx, int starty) 
    { 
     bool allPixelsWhite = false; 
     int whitePixels = 0; 

     for (int y = starty; y < img.Height; y++) 
     { 
      if (pixels[y][colx] >= 200) { whitePixels++; } 
      else { return false; } 
      if (whitePixels == img.Height) { allPixelsWhite = true; } 
     } 
     return allPixelsWhite; 
    } 

    public void GetPixels() 
    { 
     for (int y = 0; y < img.Height; y++) 
     { 
      int[] line = new int[img.Width]; 
      for (int x = 0; x < img.Width; x++) 
      { 
       line[x] = (int) img.GetPixel(x, y).R; 
      } 
      pixels.Add(line); 
     } 
    } 

    public Bitmap CropImage(Bitmap tImg, Rectangle area) 
    { 
     Bitmap bmp = new Bitmap(tImg); 
     Bitmap bmpCrop = bmp.Clone(area, bmp.PixelFormat); 
     return bmpCrop; 
    } 
} 

ответ

1

Ваш метод кажется, что это будет удивительно неэффективным - если изображение 175 пикселей в ширину, и совсем белый, вы собираетесь создать 175 его копий, ранее (возможно) сбиваться при попытке создать 0 пикселей.

Почему бы не исследовать каждый столбец поочередно, пока вы не найдете небелый столбец, а затем выполните одно растение в это время. Непроверенный код, и с другими изменениями, надеюсь очевидными:

public Bitmap CropImage (Bitmap image) 
{ 
    int top = 0; 
    int bottom = image.Height-1; 
    int left = 0; 
    int right = image.Width-1; 
    while(left < right && CheckColIfWhite(image,left)) 
     left++; 
    if(left==right) return null; //Entirely white 
    while(CheckColIfWhite(image,right)) //Because left stopped, we know right will also 
     right--; 
    while(CheckRowIfWhite(image,top)) 
     top++; 
    while(CheckRowIfWhite(image,bottom)) 
     bottom--; 
    return CropImage(image,new Rectangle(left,top,right-left+1,bottom-top+1)); 
} 

(Например, я сейчас проходящего изображение вокруг, я изменил CheckColIfWhite и CheckRowIfWhite взять изображение также и предположить, что один параметр всегда фиксированный при 0)


Кроме того, не уверен, почему вы извлекая массив пикселей заранее, поэтому я ставлю мой переписана CheckColIfWhite тоже:

public bool CheckColIfWhite(Bitmap image,int colx) 
{ 
    for (int y = 0; y < image.Height; y++) 
    { 
     if (image.GetPixel(colx,y).R < 200) 
      return false; 
    } 
    return true; 
} 
+0

Это было v Спасибо, спасибо. Я знал, что мой метод неэффективен, просто не видел лучшего способа сделать это. Первоначально я захватил все пиксели изображения, чтобы сохранить их из нескольких файлов. – sjensen85