2017-04-13 9 views
1

다음 코드를 사용하여 이미지 주변의 공백을 제거하고 있습니다. 내가 비트 맵 트리밍으로 인해 아래쪽에있는 텍스트가 자르다

enter image description here

을 트리밍 한 후하지만 다음과 같은 결과를 얻을 트리밍 한 후 다음과 같이한다 좋았지 적절한 이미지에 그린 텍스트와 비트 맵을 손질하기 위해 노력하고있어

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

+0

당신이 보여주는 이미지가 저를 혼란스럽게합니다. 알파 == 0은 어디에 있습니까? 그리고 결과는 어느 부분입니까? thw 빨간색 상자 안에 그냥 부분 ?? 당신은 a == 0 또는 == 255 인 날카로운 경계를 가정하고 반투명 한 픽셀을 가지고 있다고 가정합니다. 이미지에서 알기 힘듭니다. 어쩌면 문턱 값은 0을 테스트하는 것보다 더 잘 작동합니다. – TaW

+1

@TaW 아래쪽의 텍스트를 자르려면 빨간색 상자를 그립니다. 예를 들어 첫 번째와 두 번째 이미지의 '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); 

그것을 작동합니다.

펜과 종이로 테스트 할 수 있습니다. 첫 번째 픽셀 행은 색상 = 4, 첫 번째는 10 픽셀 정사각형의 아래쪽에서 : 8, 넷이 아닌 넷 데이터 : 4,5,6,7, 8.

이 문제가 FromLTRB에서 내재되어 있습니다 수행합니다 Rectangle

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

..results Height=100..10 생각과 11 픽셀 행을 포함해야한다! 따라서 Right-Bottom 좌표는 실제로 입니다. 결과에서을 제외했습니다!

하나의 직사각형이있는 전체 문제는 legacy ways to use a Pen with its alignment에서 유래한다고 생각합니다. Brush으로 채우기 위해 동일한 사각형을 사용할 때 모두 예상대로 작동합니다.

+0

답장과 노력에 감사드립니다. 문제가 해결되었습니다. – techno