2010-07-17 71 views
5

我试图从图像中删除所有白色或透明像素,留下实际图像(裁剪)。我已经尝试了一些解决方案,但似乎没有任何工作。任何建议,或我会花一夜写图像裁剪代码?C# - 裁剪透明/空白

+0

所以有谁的梦想的一遍又一遍的汽车无编写代码的同一行的其他人呢?我以为我是唯一一个:-) – 2010-07-17 11:54:32

+1

如果你至少详细介绍一种方法,并解释它如何工作,它会帮助社区。 – 2010-07-17 11:58:43

回答

3
public Bitmap CropBitmap(Bitmap original) 
{ 
    // determine new left 
    int newLeft = -1; 
    for (int x = 0; x < original.Width; x++) 
    { 
     for (int y = 0; y < original.Height; y++) 
     { 
      Color color = original.GetPixel(x, y); 
      if ((color.R != 255) || (color.G != 255) || (color.B != 255) || 
       (color.A != 0)) 
      { 
       // this pixel is either not white or not fully transparent 
       newLeft = x; 
       break; 
      } 
     } 
     if (newLeft != -1) 
     { 
      break; 
     } 

     // repeat logic for new right, top and bottom 

    } 

    Bitmap ret = new Bitmap(newRight - newLeft, newTop - newBottom); 
    using (Graphics g = Graphics.FromImage(ret) 
    { 
     // copy from the original onto the new, using the new coordinates as 
     // source coordinates for the original 
     g.DrawImage(...); 
    } 

    return ret 
} 

请注意,这个功能会很慢,因为脏东西。 GetPixel()的速度令人难以置信,并且访问循环内的Bitmap的属性WidthHeight也很慢。 LockBits将是正确的方法 - StackOverflow上有很多示例。

+1

谢谢,这让我在那里一半。唯一的问题是,如果图像大于指定大小,我也想调整图像大小。还有更多的代码可以放在评论框中,但原始图片只占最终图片的一半左右。该代码在http://pastebin.com/He3S8aCH – Echilon 2010-07-18 09:00:11

+0

我调换了两个变量:P。问题修复后,很快就会有博客文章(将在此链接)。 – Echilon 2010-07-18 18:33:55

+0

我想我也搞砸了。由于白色像素的R,G和B值分别为255(RGB为0,0, 0是黑色的)。如果原始版本适合您,那么它可能只会裁剪透明(和黑色)像素。 – MusiGenesis 2010-07-19 01:05:10

2

每像素检查应该做的伎俩。扫描每一行,从顶部找到空行&底部,扫描每一行以找到左边的&正确的约束(这可以用一行或一列完成)。当找到约束时 - 将图像的一部分复制到另一个缓冲区。

9

所以,你想要做的是找到顶部,最左边的非白色/透明像素和底部,最右边非白色/透明像素。这两个坐标将给你一个矩形,然后你可以提取。

// Load the bitmap 
    Bitmap originalBitmap = Bitmap.FromFile("d:\\temp\\test.bmp") as Bitmap; 

    // Find the min/max non-white/transparent pixels 
    Point min = new Point(int.MaxValue, int.MaxValue); 
    Point max = new Point(int.MinValue, int.MinValue); 

    for (int x = 0; x < originalBitmap.Width; ++x) 
    { 
    for (int y = 0; y < originalBitmap.Height; ++y) 
    { 
     Color pixelColor = originalBitmap.GetPixel(x, y); 
     if (!(pixelColor.R == 255 && pixelColor.G == 255 && pixelColor.B == 255) 
     || pixelColor.A < 255) 
     { 
     if (x < min.X) min.X = x; 
     if (y < min.Y) min.Y = y; 

     if (x > max.X) max.X = x; 
     if (y > max.Y) max.Y = y; 
     } 
    } 
    } 

    // Create a new bitmap from the crop rectangle 
    Rectangle cropRectangle = new Rectangle(min.X, min.Y, max.X - min.X, max.Y - min.Y); 
    Bitmap newBitmap = new Bitmap(cropRectangle.Width, cropRectangle.Height); 
    using (Graphics g = Graphics.FromImage(newBitmap)) 
    { 
    g.DrawImage(originalBitmap, 0, 0, cropRectangle, GraphicsUnit.Pixel); 
    } 
+0

伟大的解决方案!我删除了|| pixelColor.A <255'使其工作。 – krlzlx 2017-04-10 10:46:54

0

我发现了一种在大约10分钟内批量修剪几千个.jpg文件的方法,但是我没有在代码中完成。我使用了Snag-It Editor的Convert功能。我不知道这是否是一种选择,如果您需要修改一次或者您的需求正在进行,但是对于软件的价格(这并不是很多),我认为这是一个体面的解决方法。 (我不工作或代表的TechSmith。)

乔伊