不知道C#有没有这个功能,根据图标找到它在屏幕的位置。
例如:我保存了一个“我的电脑”的图片。我运行程序,程序会自动找到“我的电脑”这个图标在电脑
上的位置,并把鼠标移动到那个位置。
不知道C#可以实现这个功能吗?
------解决思路----------------------
/// <summary>
/// 找图类
/// </summary>
class ImageFindPoint
{
static string dsa23 = "请务尝试破解,我们将上传您的资料至网警...";
/// <summary>
/// 找小图
/// </summary>
/// <param name="sourceBitmap">大图</param>
/// <param name="partBitmap">小图</param>
/// <param name="tolerantError">匹配度(0-255) 0为完全匹配</param>
/// <param name="maxErrorPoints">错点数量</param>
/// <returns>返回坐标</returns>
private Point FindImage_(Bitmap sourceBitmap, Bitmap partBitmap, int tolerantError, int maxErrorPoints)
{
int w0 = sourceBitmap.Width, h0 = sourceBitmap.Height, w = partBitmap.Width, h = partBitmap.Height;
var bmp1 = sourceBitmap.LockBits(new Rectangle(0, 0, w0, h0), ImageLockMode.ReadOnly, PixelFormat.Format32bppPArgb);
var data1 = new byte[bmp1.Stride * bmp1.Height];
Marshal.Copy(bmp1.Scan0, data1, 0, bmp1.Stride * bmp1.Height);
sourceBitmap.UnlockBits(bmp1);
var bmp2 = partBitmap.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format32bppPArgb);
var data2 = new byte[bmp2.Stride * bmp2.Height];
Marshal.Copy(bmp2.Scan0, data2, 0, bmp2.Stride * bmp2.Height);
partBitmap.UnlockBits(bmp2);
int[] rgb = { 2, 1, 0 };
equals_ equals = new equals_(delegate(Point pt1_, Point pt2_)
{
int p1 = pt1_.Y * bmp1.Stride + pt1_.X * 4, p2 = pt2_.Y * bmp2.Stride + pt2_.X * 4;
return AllCompleted(rgb, data1, data2, p1, p2, tolerantError);
});
ptRP ptRP_ = new ptRP(delegate(int x_, int y_) { return new Point(x_, y_); });
var keyPts = new[] { ptRP_(0, 0), ptRP_(w - 1, 0), ptRP_(w / 2, h / 2), ptRP_(0, h - 1), ptRP_(w - 1, h - 1) };
isMatch_ isMatch = new isMatch_(delegate(Point p0_)
{
if (AnyCompleted(keyPts, p0_, equals))
return false;
int tolerant = maxErrorPoints;
for (int y = 0; y < h; y++)
for (int x = 0; x < w; x++)
if (!equals(p0_ + (Size)ptRP_(x, y), ptRP_(x, y)) && (tolerant-- <= 0))
return false;
return true;
});
for (int y = 0; y < h0 - h; y++)
for (int x = 0; x < w0 - w; x++)
if (isMatch(ptRP_(x, y)))
return ptRP_(x, y);
return ptRP_(-1, -1);
}
delegate bool equals_(Point pt1, Point pt2);
delegate Point ptRP(int x_, int y_);
delegate bool isMatch_(Point p);
private bool AllCompleted(int[] rgbints, byte[] data1, byte[] data2, int p1, int p2, int tolerantError)
{
foreach (int i in rgbints)
if (!(Math.Abs(data1[p1 + i] - data2[p2 + i]) <= tolerantError))
return false;
return true;
}
private bool AnyCompleted(Point[] keyPts, Point p0_, equals_ equals)
{
foreach (Point i in keyPts)
if (!equals(i + (Size)p0_, i))
return true;
return false;
}
/// <summary>
/// 在大图指定位置找小图 (记得范围+ - 5px)
/// </summary>
/// <param name="sourceBitmap">大图</param>
/// <param name="partBitmap">小图</param>
/// <param name="rc">指定范围(必须比小图大)</param>
/// <param name="tolerantError">匹配度(0-255) 0为完全匹配</param>
/// <param name="maxErrorPoints">错点数量</param>
/// <returns>返回坐标</returns>
public Point FindImage(Bitmap sourceBitmap, Bitmap partBitmap,Rectangle rc, int tolerantError, int maxErrorPoints)
{
try
{
Bitmap TempsourceBitmap = new Bitmap(rc.Right - rc.Left, rc.Bottom - rc.Top);
Graphics gr = Graphics.FromImage(TempsourceBitmap);
gr.DrawImage(sourceBitmap, 0, 0, new RectangleF(rc.Left, rc.Top, rc.Right - rc.Left, rc.Bottom - rc.Top), GraphicsUnit.Pixel);
gr.Dispose();
Point p = FindImage_(TempsourceBitmap, partBitmap, tolerantError, maxErrorPoints);
if (p.X == -1)
return p;
else
{
if (p.X < 0
------解决思路----------------------
p.X > rc.Width
------解决思路----------------------
p.Y < 0
------解决思路----------------------
p.Y > rc.Height)
return new Point(-1, -1);
else
return new Point(p.X + rc.Left, p.Y + rc.Top);
}
}
catch { return new Point(-1, -1); }
}
/// <summary>
/// 在大图相对位置找小图 (记得范围+ - 5px)
/// </summary>
/// <param name="sourceBitmap">大图</param>
/// <param name="partBitmap">小图</param>
/// <param name="rc">指定范围(必须比小图大)</param>
/// <param name="tolerantError">匹配度(0-255) 0为完全匹配</param>
/// <param name="maxErrorPoints">错点数量</param>
/// <returns>返回坐标</returns>
public Point FindImageR(Bitmap sourceBitmap, Bitmap partBitmap, Rectangle rc, int tolerantError, int maxErrorPoints)
{
try
{
Bitmap TempsourceBitmap = new Bitmap(rc.Right - rc.Left, rc.Bottom - rc.Top);
Graphics gr = Graphics.FromImage(TempsourceBitmap);
gr.DrawImage(sourceBitmap, 0, 0, new RectangleF(rc.Left, rc.Top, rc.Right - rc.Left, rc.Bottom - rc.Top), GraphicsUnit.Pixel);
gr.Dispose();
Point p = FindImage_(TempsourceBitmap, partBitmap, tolerantError, maxErrorPoints);
if (p.X == -1)
return p;
else
return new Point(p.X, p.Y);
}
catch { return new Point(-1, -1); }
}
/// <summary>
/// 在大图指定范围位置找小图
/// </summary>
/// <param name="sourceBitmap">大图</param>
/// <param name="partBitmap">小图</param>
/// <param name="tolerantError">匹配度(0-255) 0为完全匹配</param>
/// <param name="maxErrorPoints">错点数量</param>
/// <returns></returns>
public Point FindImage(Bitmap sourceBitmap, Bitmap partBitmap, int tolerantError, int maxErrorPoints)
{
try
{
Point p = FindImage_(sourceBitmap, partBitmap, tolerantError, maxErrorPoints);
return p;
}
catch { return new Point(-1, -1); }
}
/// <summary>
/// 比较两张图片是否完全一样
///
/// 速度慢,但匹配精确
///
/// (方法:匹配两张图片的每一个像素)
/// </summary>
private bool ImageCompareArray(Bitmap firstImage, Bitmap secondImage)
{
bool flag = true;
string firstPixel;
string secondPixel;
if (firstImage.Width == secondImage.Width && firstImage.Height == secondImage.Height)
{
for (int i = 0; i < firstImage.Width; i++)
{
for (int j = 0; j < firstImage.Height; j++)
{
firstPixel = firstImage.GetPixel(i, j).ToString();
secondPixel = secondImage.GetPixel(i, j).ToString();
if (firstPixel != secondPixel)
{
flag = false;
break;
}
}
}
if (flag == false)
{
return false;
}
else
{
return true;
}
}
else
{
return false;
}
}
/// <summary>
/// 比较两张图片是否完全一样
/// ///
/// /// 速度快,但对大图片可能有些误差
/// ///
/// /// (方法:将图片转换为Base64后,匹配Base64)
/// </summary>
public bool ImageCompareString(Bitmap firstImage, Bitmap secondImage)
{
if (firstImage == null)
return false;
MemoryStream ms = new MemoryStream();
firstImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
String firstBitmap = Convert.ToBase64String(ms.ToArray());
ms.Position = 0;
secondImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
String secondBitmap = Convert.ToBase64String(ms.ToArray());
if (firstBitmap.Equals(secondBitmap))
{
return true;
}
else
{
return false;
}
}
}
给你代码 你也不一定能理解。
------解决思路----------------------
class ImageGet
{
static IntPtr dc1 = IntPtr.Zero;
static IntPtr dc2 = IntPtr.Zero;
static IntPtr dc3 = IntPtr.Zero;
static Bitmap MyImage = null;
/// <summary>
/// 截取模拟器客户区图片
/// </summary>
/// <param name="hwnd">句柄</param>
/// <returns></returns>
public static Bitmap GetImgDesk(IntPtr hwnd)
{
ks:
try
{
if (hwnd == IntPtr.Zero)
{
return null;
}
SystemApi.RECT rc = new SystemApi.RECT();
SystemApi.GetWindowRect(hwnd, out rc);
SystemApi.PointApi p = new SystemApi.PointApi();
SystemApi.ScreenToClient(hwnd, out p);
//设置客户区的坐标
SimulatorInfo.MainClientLack = new Point(Math.Abs(p.x) - rc.left, Math.Abs(p.y) - rc.top);
SystemApi.RECT rcc = new SystemApi.RECT();
SystemApi.GetClientRect(hwnd, out rcc);
dc1 = SystemApi.CreateDC("DISPLAY", null,
null, (IntPtr)null);
//创建显示器的DC
Graphics g1 = Graphics.FromHdc(dc1);
//由一个指定设备的句柄创建一个新的Graphics对象
MyImage = new Bitmap(rcc.right, rcc.bottom, g1);
//根据屏幕大小创建一个与之相同大小的Bitmap对象
Graphics g2 = Graphics.FromImage(MyImage);
//获得屏幕的句柄
dc3 = g1.GetHdc();
//获得位图的句柄
dc2 = g2.GetHdc();
//把当前屏幕捕获到位图对象中
SystemApi.BitBlt(dc2, 0, 0, rcc.right,
rcc.bottom,
dc3, Math.Abs(p.x), Math.Abs(p.y), 13369376);
//把当前屏幕拷贝到位图中
g1.ReleaseHdc(dc3);
//释放屏幕句柄
g2.ReleaseHdc(dc2);
//释放位图句柄
g1.Dispose();
g2.Dispose();
return MyImage;
}
catch { MessageBox.Show("软件运行过程中,请勿关闭或最小化模拟器!", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
hwnd= tdb.SimulatorInfo.MainHwnd;
Thread.Sleep(500);
goto ks; }
}
#region 截取模拟器客户区指定范围保存图片
public static string a = "abcdefjhijklmnopqrstuvwxyz0123456789";
/// <summary>
/// 截取模拟器客户区指定范围保存图片
/// </summary>
/// <param name="hwnd">句柄</param>
/// <param name="ec">截取范围</param>
/// <returns></returns>
public static Bitmap GetImgDesk(IntPtr hwnd, Rectangle ec)
{
SystemApi.RECT rc = new SystemApi.RECT();
SystemApi.GetWindowRect(hwnd, out rc);
SystemApi.PointApi p = new SystemApi.PointApi();
SystemApi.ScreenToClient(hwnd, out p);
dc1 = SystemApi.CreateDC("DISPLAY", null,
null, (IntPtr)null);
//创建显示器的DC
Graphics g1 = Graphics.FromHdc(dc1);
//由一个指定设备的句柄创建一个新的Graphics对象
MyImage =
new Bitmap(ec.Width, ec.Height, g1);
//根据屏幕大小创建一个与之相同大小的Bitmap对象
Graphics g2 = Graphics.FromImage(MyImage);
//获得屏幕的句柄
dc3 = g1.GetHdc();
//获得位图的句柄
dc2 = g2.GetHdc();
//把当前屏幕捕获到位图对象中
SystemApi.BitBlt(dc2, 0, 0, ec.Width, ec.Height,
dc3, ec.X + Math.Abs(p.x), ec.Y + Math.Abs(p.y), 13369376);
//把当前屏幕拷贝到位图中
g1.ReleaseHdc(dc3);
//释放屏幕句柄
g2.ReleaseHdc(dc2);
//释放位图句柄
g1.Dispose();
g2.Dispose();
return MyImage;
}
#endregion
}
句柄传桌面句柄即可。想要又快有准。哪有这么好的事。
如果你只是想获取桌面有哪些图标。然后打开相应的程序。这个自然不需要找图。
不找图效率就很高。
如果你是新手。就不要随便例如。应该说 我现在想做什么功能。我想用找图方法。
如果别人认为用找图方法合适。自然会给你代码。
如果不合适。人家会告诉你怎么做合适。
所以 不要自认为自己例如得很好。 建议你把你要做的东西说出来。让大家看看