【发布时间】:2015-08-14 15:58:46
【问题描述】:
我开发了一个屏幕共享应用程序,我想让它尽可能高效,所以我试图只发送屏幕截图之间的差异。 所以,假设我们有这个图像,例如:它是一个 32bpprgba 图像,周围有透明的部分。
我想将此处的每个块作为矩形存储在列表中并获取它们的边界。听起来可能很复杂,但实际上它只需要一点逻辑。 到目前为止,这是我的代码:
private unsafe List<Rectangle> CodeImage(Bitmap bmp)
{
List<Rectangle> rec = new List<Rectangle>();
Bitmap bmpRes = new Bitmap(bmp.Width, bmp.Height);
BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat);
IntPtr scan0 = bmData.Scan0;
int stride = bmData.Stride;
int nWidth = bmp.Width;
int nHeight = bmp.Height;
int minX = int.MaxValue; ;
int minY = int.MaxValue;
int maxX = 0;
bool found = false;
for (int y = 0; y < bmp.Height; y++)
{
byte* p = (byte*)scan0.ToPointer();
p += y * stride;
for (int x = 0; x < bmp.Width; x++)
{
if (p[3] != 0) //Check if pixel is not transparent;
{
found = true;
if (x < minX)
minX = x;
if (x > maxX)
maxX = x;
if (y < minY)
minY = y;
}
else
{
if (found)
{
int height = getBlockHeight(stride, scan0, maxX, minY);
found = false;
Rectangle temp = new Rectangle(minX, minY, maxX - minX, height);
rec.Add(temp);
y += minY;
break;
}
}
p += 4;//add to the pointer 4 bytes;
}
}
return rec;
}
如您所见,我试图使用高度和宽度扫描图像,当我找到一个像素时,我将其发送到 GetBlockHeight 函数以获取它的高度:
public unsafe int getBlockHeight(int stride, IntPtr scan, int x, int y1)
{
int height = 0; ;
for (int y = y1; y < 1080; y++)
{
byte* p = (byte*)scan.ToPointer();
p += (y * stride) + (x * 4);
if (p[3] != 0) //Check if pixel is not transparent;
{
height++;
}
}
return height;
}
但我只是没有得到结果......我认为这里的逻辑有些东西......谁能点亮我的眼睛?我知道这需要一些时间和思考,但我非常感谢任何可以提供一点帮助的人。
【问题讨论】:
-
看来
maxX永远是int.MaxValue。您还需要在匹配块后重置它。此外,从长远来看,您想支持什么?同一垂直位置上的多个矩形?非矩形区域? -
@C.Evenhui 目前只有矩形区域。关于
maxX是的,你是对的.. 改变了它,但它仍然不是很接近...... 是的,我猜同一行会有多个矩形。 -
@C.Evenhuis 你说的重置是什么意思?打破循环并启动价值观?如果您能多解释一点或举一个简单的例子,我将不胜感激。谢谢。
-
@C.Evenhuis 还在吗?
标签: c# image-processing screenshot