I have a black and white System.Drawing.Bitmap I need to auto-crop it so that it is only as big as needed to fit the image. This image always starts at the top left (0,0) position but I'm not sure how much height and width is will require. If there any way to auto-crop it to size?
- What the image contains on the blank area? white or transparent pixels?Gilad Naaman– Gilad Naaman2011-08-11 20:39:48 +00:00Commented Aug 11, 2011 at 20:39
- 2Ummm... I don't know if it's very efficient, but I would search for the last line of pixels that is all white (Or first from the last) and get it's number. Same for column.Gilad Naaman– Gilad Naaman2011-08-11 21:01:30 +00:00Commented Aug 11, 2011 at 21:01
Add a comment |
2 Answers
The following is the code I used:
// Figure out the final size int maxX = 0; int maxY = 0; for (int x = 0; x < bitmap.Width; x++) { for (int y = 0; y < bitmap.Height; y++) { System.Drawing.Color c = bitmap.GetPixel(x, y); System.Drawing.Color w = System.Drawing.Color.White; if (c.R != w.R || c.G != w.G || c.B != w.B) { if (x > maxX) maxX = x; if (y > maxY) maxY = y; } } } maxX += 2; 2 Comments
Kaleb Pederson
I don't know any data on your images, but it feels like you could speed things by bisecting your image, checking for any non-white values which would tell you which half to bisect... and so on. You might be able to achieve O((log h)*(log w)) worst-case time instead of O(w*h).
Kaleb Pederson
I guess that would work for closed shapes, but probably not an image that contained only two non-blank pixels. Oh well, worth considering depending on the image.
If your image does not start at 0,0 like mine, here is a variant that gets you the auto-crop bounds:
public static Rectangle GetAutoCropBounds(Bitmap bitmap) { int maxX = 0; int maxY = 0; int minX = bitmap.Width; int minY = bitmap.Height; for (int x = 0; x < bitmap.Width; x++) { for (int y = 0; y < bitmap.Height; y++) { var c = bitmap.GetPixel(x, y); var w = Color.White; if (c.R != w.R || c.G != w.G || c.B != w.B) { if (x > maxX) maxX = x; if (x < minX) minX = x; if (y > maxY) maxY = y; if (y < minY) minY = y; } } } maxX += 2; return new Rectangle(minX, minY, maxX - minX, maxY - minY); } Note: if you are processing any amount of images in quantity or high-resolution then you'll want to look into faster alternatives than the GetPixel method.