2017-04-13 79 views
1

導致文本的剪切,我用下面的代碼刪除圖像周圍的空白。修剪位圖在底部

static Bitmap TrimBitmap(Bitmap source) 
     { 
      Rectangle srcRect = default(Rectangle); 
      BitmapData data = null; 
      try 
      { 
       data = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); 
       byte[] buffer = new byte[data.Height * data.Stride]; 
       Marshal.Copy(data.Scan0, buffer, 0, buffer.Length); 

       int xMin = int.MaxValue, 
        xMax = int.MinValue, 
        yMin = int.MaxValue, 
        yMax = int.MinValue; 

       bool foundPixel = false; 

       // Find xMin 
       for (int x = 0; x < data.Width; x++) 
       { 
        bool stop = false; 
        for (int y = 0; y < data.Height; y++) 
        { 
         byte alpha = buffer[y * data.Stride + 4 * x + 3]; 
         if (alpha != 0) 
         { 
          xMin = x; 
          stop = true; 
          foundPixel = true; 
          break; 
         } 
        } 
        if (stop) 
         break; 
       } 

       // Image is empty... 
       if (!foundPixel) 
        return null; 

       // Find yMin 
       for (int y = 0; y < data.Height; y++) 
       { 
        bool stop = false; 
        for (int x = xMin; x < data.Width; x++) 
        { 
         byte alpha = buffer[y * data.Stride + 4 * x + 3]; 
         if (alpha != 0) 
         { 
          yMin = y; 
          stop = true; 
          break; 
         } 
        } 
        if (stop) 
         break; 
       } 

       // Find xMax 
       for (int x = data.Width - 1; x >= xMin; x--) 
       { 
        bool stop = false; 
        for (int y = yMin; y < data.Height; y++) 
        { 
         byte alpha = buffer[y * data.Stride + 4 * x + 3]; 
         if (alpha != 0) 
         { 
          xMax = x; 
          stop = true; 
          break; 
         } 
        } 
        if (stop) 
         break; 
       } 

       // Find yMax 
       for (int y = data.Height - 1; y >= yMin; y--) 
       { 
        bool stop = false; 
        for (int x = xMin; x <= xMax; x++) 
        { 
         byte alpha = buffer[y * data.Stride + 4 * x + 3]; 
         if (alpha != 0) 
         { 
          yMax = y; 
          stop = true; 
          break; 
         } 
        } 
        if (stop) 
         break; 
       } 
       srcRect = Rectangle.FromLTRB(xMin, yMin, xMax , yMax); 
      } 
      finally 
      { 
       if (data != null) 
        source.UnlockBits(data); 
      } 

      Bitmap dest = new Bitmap(srcRect.Width, srcRect.Height); 
      Rectangle destRect = new Rectangle(0, 0, srcRect.Width, srcRect.Height); 
      using (Graphics graphics = Graphics.FromImage(dest)) 
      { 
       graphics.DrawImage(source, destRect, srcRect, GraphicsUnit.Pixel); 
      } 
      return dest; 
     } 

我試圖用修剪上畫出後援正確的圖像文本位圖應該是這樣的微調

enter image description here

之後,但修剪我得到以下結果後..the底部剪掉

我我我做錯了什麼?請指點..

enter image description here

+0

您顯示的圖像令我困惑。 alpha == 0在哪裏?哪一部分是結果?只是紅色框內的部分?你假設有一個尖銳的邊界,其中== 0或== 255可能是錯誤的,並且你有半透明的像素..很難從圖像中分辨出來。也許閾工作竟被比對測試0 – TaW

+1

@TaW我畫紅色框來顯示文本的底部部分切割..例如,從第一和第二image.Plus我比較's'在單獨的圖像上繪製該文本('新的位圖(somewidth,someheight)')並在另一個圖像上繪製文本位圖。 – techno

+0

@TaW嗯..好的..你能否請更新代碼併爲我回答? – techno

回答

1

這實際上是Rectangle.FromLTRB問題!

仔細觀察圖像,您會發現實際上只丟失了一排一行像素。 (強倍率讓我上當了一會兒..)

的算法來確定矩形的高度(和寬度)基本上是正確的,但關閉的一個

如果使用此

srcRect = Rectangle.FromLTRB(xMin, yMin, xMax + 1 , yMax + 1); 

或本:

srcRect = new Rectangle(xMin, yMin, xMax - xMin + 1 , yMax - yMin + 1); 

它應該工作。從底部上的10像素正方形第一像素行與彩色= 4,第一::8,使5中未4淨數據:

可以與筆和紙測試:說4,5,6,7, 8。

注意,這問題是固有FromLTRB

Rectangle myRectangle = Rectangle.FromLTRB(0, 0, 10, 10); 

..results在RectangleHeight=10即使0..10應涵蓋11像素行!所以Right-Bottom座標實際上是從結果中排除了

我想用矩形用一個被關閉的整個問題由legacy ways to use a Pen with its alignment莖。按照預期使用相同的矩形填充Brush所有的作品。

+0

非常感謝您的回答和努力。這已解決了我的問題.. – techno