Remove surrounding whitespace from an image

前端 未结 8 856
时光说笑
时光说笑 2020-12-02 15:54

I have a block of product images we received from a customer. Each product image is a picture of something and it was taken with a white background. I would like to crop a

相关标签:
8条回答
  • 2020-12-02 16:34

    Here's my (rather lengthy) solution:

    public Bitmap Crop(Bitmap bmp)
    {
      int w = bmp.Width, h = bmp.Height;
    
      Func<int, bool> allWhiteRow = row =>
      {
        for (int i = 0; i < w; ++i)
          if (bmp.GetPixel(i, row).R != 255)
            return false;
        return true;
      };
    
      Func<int, bool> allWhiteColumn = col =>
      {
        for (int i = 0; i < h; ++i)
          if (bmp.GetPixel(col, i).R != 255)
            return false;
        return true;
      };
    
      int topmost = 0;
      for (int row = 0; row < h; ++row)
      {
        if (allWhiteRow(row))
          topmost = row;
        else break;
      }
    
      int bottommost = 0;
      for (int row = h - 1; row >= 0; --row)
      {
        if (allWhiteRow(row))
          bottommost = row;
        else break;
      }
    
      int leftmost = 0, rightmost = 0;
      for (int col = 0; col < w; ++col)
      {
        if (allWhiteColumn(col))
          leftmost = col;
        else
          break;
      }
    
      for (int col = w-1; col >= 0; --col)
      {
        if (allWhiteColumn(col))
          rightmost = col;
        else
          break;
      }
    
      int croppedWidth = rightmost - leftmost;
      int croppedHeight = bottommost - topmost;
      try
      {
        Bitmap target = new Bitmap(croppedWidth, croppedHeight);
        using (Graphics g = Graphics.FromImage(target))
        {
          g.DrawImage(bmp,
            new RectangleF(0, 0, croppedWidth, croppedHeight),
            new RectangleF(leftmost, topmost, croppedWidth, croppedHeight),
            GraphicsUnit.Pixel);
        }
        return target;
      }
      catch (Exception ex)
      {
        throw new Exception(
          string.Format("Values are topmost={0} btm={1} left={2} right={3}", topmost, bottommost, leftmost, rightmost),
          ex);
      }
    }
    
    0 讨论(0)
  • 2020-12-02 16:40

    fix remaining 1px white space at the top and left

        public Bitmap Crop(Bitmap bitmap)
        {
            int w = bitmap.Width;
            int h = bitmap.Height;
    
            Func<int, bool> IsAllWhiteRow = row =>
            {
                for (int i = 0; i < w; i++)
                {
                    if (bitmap.GetPixel(i, row).R != 255)
                    {
                        return false;
                    }
                }
                return true;
            };
    
            Func<int, bool> IsAllWhiteColumn = col =>
            {
                for (int i = 0; i < h; i++)
                {
                    if (bitmap.GetPixel(col, i).R != 255)
                    {
                        return false;
                    }
                }
                return true;
            };
    
            int leftMost = 0;
            for (int col = 0; col < w; col++)
            {
                if (IsAllWhiteColumn(col)) leftMost = col + 1;
                else break;
            }
    
            int rightMost = w - 1;
            for (int col = rightMost; col > 0; col--)
            {
                if (IsAllWhiteColumn(col)) rightMost = col - 1;
                else break;
            }
    
            int topMost = 0;
            for (int row = 0; row < h; row++)
            {
                if (IsAllWhiteRow(row)) topMost = row + 1;
                else break;
            }
    
            int bottomMost = h - 1;
            for (int row = bottomMost; row > 0; row--)
            {
                if (IsAllWhiteRow(row)) bottomMost = row - 1;
                else break;
            }
    
            if (rightMost == 0 && bottomMost == 0 && leftMost == w && topMost == h)
            {
                return bitmap;
            }
    
            int croppedWidth = rightMost - leftMost + 1;
            int croppedHeight = bottomMost - topMost + 1;
    
            try
            {
                Bitmap target = new Bitmap(croppedWidth, croppedHeight);
                using (Graphics g = Graphics.FromImage(target))
                {
                    g.DrawImage(bitmap,
                        new RectangleF(0, 0, croppedWidth, croppedHeight),
                        new RectangleF(leftMost, topMost, croppedWidth, croppedHeight),
                        GraphicsUnit.Pixel);
                }
                return target;
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("Values are top={0} bottom={1} left={2} right={3}", topMost, bottomMost, leftMost, rightMost), ex);
            }
        }
    
    0 讨论(0)
提交回复
热议问题