c# GDI边缘空白检测算法
我正在寻找一种从 c# 托管 GDI+ 库中检测 c# 位图边缘空白的解决方案。
图像可以是透明或白色,大多数 400x 图片的尺寸为 8000x8000 像素,边缘周围有大约 2000 像素的空白。
找出边缘、x、y、高度和宽度坐标的最有效方法是什么? 我尝试逐像素进行,但发现速度非常慢。
解决方案更新 --添加了左/右/上/下边界
图像细节中心图像的问题,现在裁剪任何透明(0%)或白色(#FFFFFF)像素。
var top = bitmap.Height;
var left = bitmap.Width;
var right = 0;
var bottom = 0;
……
var pData = pData0 + (y * data.Stride) + (x * 4);
var xyAlpha = pData[3];
var xyBlue = pData[0];
var xyGreen = pData[1];
var xyRed = pData[2];
if ((xyAlpha > 0) || (xyRed != 255 && xyGreen != 255 && xyBlue != 255)) {
if (y < top)
top = y;
if (y > bottom)
bottom = y;
if (x < left)
left = x;
if (x > right)
right = x;
}
var cropWidth = right - left;
var cropHeight = bottom - top;
var cropX = top;
var cropY = left;
var cacheBitmap = new Bitmap(cropWidth, cropHeight, PixelFormat.Format32bppArgb);
using (var cacheGraphics = Graphics.FromImage(cacheBitmap)) {
cacheGraphics.DrawImage(context.Image, new Rectangle(0, 0, cropWidth, cropHeight), cropX, cropY, cropWidth, cropHeight, GraphicsUnit.Pixel);
}
I am looking for a solution for detecting edge whitespace of c# bitmap, from the c# managed GDI+ library.
The images would be either transparent or white, most of the 400x pictures are 8000x8000px with about 2000px whitespace around the edges.
What would be the most efficient way of finding out the edges, x, y, height and width coordinates? I tried a go pixel by pixel but was finding it very slow.
Update to solution
--Added left/right/top/bottom bounds
Problems with images detail center images, now crops any transparent (0%) or white (#FFFFFF) pixels.
var top = bitmap.Height;
var left = bitmap.Width;
var right = 0;
var bottom = 0;
...
var pData = pData0 + (y * data.Stride) + (x * 4);
var xyAlpha = pData[3];
var xyBlue = pData[0];
var xyGreen = pData[1];
var xyRed = pData[2];
if ((xyAlpha > 0) || (xyRed != 255 && xyGreen != 255 && xyBlue != 255)) {
if (y < top)
top = y;
if (y > bottom)
bottom = y;
if (x < left)
left = x;
if (x > right)
right = x;
}
...
var cropWidth = right - left;
var cropHeight = bottom - top;
var cropX = top;
var cropY = left;
var cacheBitmap = new Bitmap(cropWidth, cropHeight, PixelFormat.Format32bppArgb);
using (var cacheGraphics = Graphics.FromImage(cacheBitmap)) {
cacheGraphics.DrawImage(context.Image, new Rectangle(0, 0, cropWidth, cropHeight), cropX, cropY, cropWidth, cropHeight, GraphicsUnit.Pixel);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Bob Powell 的 GDI+ 常见问题解答!
您没有说明如何访问图像中的像素,因此我假设您使用了缓慢的 GetPixel 方法。 您可以使用指针和 LockBits 以更快的方式访问像素: 参见 Bob Powells 对 LockBits 的解释
下面的代码使用 LockBits 方法(对于 PixelFormat.Format32bppArgb )并将用发现图像中第一个和最后一个像素不具有参数颜色中描述的颜色的值填充开始点和结束点。 该方法还忽略完全透明的像素,如果您想检测可见“内容”开始的图像区域,这非常有用。
A great GDI+ resource is Bob Powell's GDI+ FAQ!
You didn't say how you accessed the pixels in the image so I will assume that you used the slow GetPixel methods. You can use pointers and LockBits to access pixels in a faster way: see Bob Powells explanation of LockBits
The below code uses the LockBits approach (for the PixelFormat.Format32bppArgb) and will fill the start and end Points with the value where the first and last pixels in an image are discovered that do not have the color described in the argument color. The method also ignores completely transparent pixels which is useful if you want to detect the area of an image where the visible 'content' starts.
我首先确保使用 Patrick 描述的 LockBits 方法。 其次,我会检查中间线上的像素以快速确定边缘。 我所说的中间线是指,如果你说一个 2000x1000 的图像,你会首先沿着水平线编号 500(满分 1000)查找左右限制,然后沿着垂直线编号 1000(满分 2000)查找找到上限和下限。 这样应该会很快。
I'd first make sure to use the LockBits method described by Patrick. Second I'd check the pixels on the middle lines to quickly determine the edges. By middle lines I mean, if you have say for example a 2000x1000 image, you'd look first along horizontal line number 500 (out of 1000) to find the left and right limits, then along vertical line number 1000 (out of 2000) to find the top and bottom limits. It should be very fast this way.