修剪位图在底部

问题描述:

导致文本的剪切,我用下面的代码删除图像周围的空白。修剪位图在底部

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

这实际上是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