什么吗
我有一个应用程序,它通过颜色代码扫描我的屏幕图像。
问题!
此过程耗时太长,因为搜索整个屏幕。
我的目标
我想搜索当前鼠标位置周围的区域。 但是我该怎么做?
代码
这是我的代码:
创建一个屏幕
private Bitmap CaptureScreen()
{
//Point a = new Point();
//a = Control.MousePosition;
Bitmap b = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
using (Graphics g = Graphics.FromImage(b))
{
g.CopyFromScreen(new Point(0, 0), new Point(0, 0), b.Size);
}
return b;
}
搜索颜色代码
public Point GetPixelPosition(Color SearchColor, bool IgnoreAlphaChannel)
{
//Point a = new Point();
//a = Control.MousePosition;
_ColorFound = false;
Point PixelPt = new Point(0, 0);
using (Bitmap b = CaptureScreen())
{
for (int i = 0; i < b.Width; i++)
{
if (this._ColorFound)
break;
for (int j = 0; j < b.Height; j++)
{
if (this._ColorFound)
break;
Color tmpPixelColor = b.GetPixel(i, j);
if (((tmpPixelColor.A == SearchColor.A) || IgnoreAlphaChannel)
&& (tmpPixelColor.R == SearchColor.R)
&& (tmpPixelColor.G == SearchColor.G)
&& (tmpPixelColor.B == SearchColor.B)
)
{
PixelPt.X = i;
PixelPt.Y = j;
this._ColorFound = true;
}
}
}
}
return PixelPt;
}
答案 0 :(得分:0)
我认为你的扫描方式非常有效......但在这个答案中,我的目标是通过使用你的代码来完成你想要的东西(我还没有完全优化)任何东西):
public Point GetPixelPosition(Color SearchColor, bool IgnoreAlphaChannel, int pixelsToSearchAround)
{
Point mousePosition = Cursor.Position;
_ColorFound = false;
Point PixelPt = new Point(0, 0);
using (Bitmap b = CaptureScreen())
{
int minX = mousePosition.X - pixelsToSearchAround;
int maxX = mousePosition.X + pixelsToSearchAround;
int minY = mousePosition.Y - pixelsToSearchAround;
int maxY = mousePosition.Y + pixelsToSearchAround;
if(minX < 0) minX = 0;
if(minY < 0) minY = 0;
if(maxX > b.Width) maxX = b.Width;
if(maxY > b.Height) maxY = b.Height;
for (int i = minX; i < maxX; i++)
{
if (this._ColorFound)
break;
for (int j = minY; j < maxY; j++)
{
if (this._ColorFound)
break;
Color tmpPixelColor = b.GetPixel(i, j);
if (((tmpPixelColor.A == SearchColor.A) || IgnoreAlphaChannel)
&& (tmpPixelColor.R == SearchColor.R)
&& (tmpPixelColor.G == SearchColor.G)
&& (tmpPixelColor.B == SearchColor.B)
)
{
PixelPt.X = i;
PixelPt.Y = j;
this._ColorFound = true;
}
}
}
}
return PixelPt;
}
这应该以一种非常不优化的方式做你想要的事情:它不是我在屏幕上搜索像素组件所做的。
您可以使用第三个参数来确定要搜索的光标周围的像素数。
为了进一步优化,您只能捕获您想要捕获的屏幕区域,但我会将其留给您(提示:而不是在GetPixelPosition
中执行此操作,您可以执行此操作在CaptureScreen
中,修改g.CopyFromScreen
的参数,而不是修改循环边界。)
答案 1 :(得分:0)
您可以改善颜色检查方法的性能,而不是限制区域。
不要使用Bitmap.GetPixel
!请改用Bitmap.UnlockBits
。
public static unsafe Point GetPoint (Bitmap bmp, Color c) {
BitmapData bmd = bmp.LockBits (new Rectangle(0,0,bmp.Width,bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
try {
int s = bmd.Stride;
int search = (c.A<<0x18)|(c.R<<0x10)|(c.G<<0x08)|c.B;
int* clr = (int*)(void*)bmd.Scan0;
int tmp;
int* row = clr;
for (int i = 0; i < bmp.Height; i++) {
int* col = row;
for (int j = 0; j < bmp.Width; j++) {
tmp = *col;
if(tmp == search) {
return new Point(j,i);
}
col++;
}
row += s>>0x02;
}
return new Point(-1,-1);
} finally {
bmp.UnlockBits (bmd);
}
}
如果找不到颜色,此方法将返回(-1,-1)
。您可以对其进行调整以忽略alpha
- 频道:
public static unsafe Point GetPoint (Bitmap bmp, Color c, bool ignoreAlpha = false) {
BitmapData bmd = bmp.LockBits (new Rectangle(0,0,bmp.Width,bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
try {
int s = bmd.Stride;
int search = (c.A<<0x18)|(c.R<<0x10)|(c.G<<0x08)|c.B;
if(ignoreAlpha) {
search &= 0xffffff;
}
int* clr = (int*)(void*)bmd.Scan0;
int tmp;
int* row = clr;
for (int i = 0; i < bmp.Height; i++) {
int* col = row;
for (int j = 0; j < bmp.Width; j++) {
tmp = *col;
if(ignoreAlpha) {
tmp &= 0xffffff;
}
if(tmp == search) {
return new Point(j,i);
}
col++;
}
row += s>>0x02;
}
return new Point(-1,-1);
} finally {
bmp.UnlockBits (bmd);
}
}
GetPixel
较慢的原因是您不批量处理它们。这是因为该方法始终需要解码图像并等待您查询的像素走过。使用UnlockBits
只解码一次,然后迭代所有像素。