【发布时间】:2012-08-29 14:04:42
【问题描述】:
整件事是,使用CopyFromScreen() 方法,我能够将图像(先前捕获的)与与捕获的图像相同的图像进行比较,因为它实际上是从该特定屏幕捕获的。
或更简单地说,例如,从桌面裁剪并保存为图像的图标以及引用其位置(点)和大小(大小(h,w))的文本文件
所以当我们通过 File.WriteAllBytes(byte[]made it .bar) 将.bar 捕获到一个文件 + cuptured.txt 并参考位置和大小时,我们有一个副本保存到 hdd 及其位置和大小文本文件。 (我不必发布所有代码,但它工作正常,所以如果有人需要它..我随时分享)
我实现这一点的方法是使用我制作的 DoCopyFScr() 方法 - 捕捉使用 Bitmap2ByteArr() 的屏幕部分 - 将位图保存为 ByteArr
然后在需要时使用 byte[]- 保存,与屏幕上捕获的位置进行比较。
public void DoCopyFScr(Point SourceP, Size Mysz, string initDir, string Fname, bool SaveIt, bool DoCompare)
{
SetForegroundWindow(A window handle suplied here);
pause(200);
Point pZero = new Point(0, 0);
using (Bitmap bitmap = new Bitmap(Mysz.Width, Mysz.Height))
{
using (Graphics g = Graphics.FromImage(bitmap))
{
g.CopyFromScreen(SourceP, pZero, Msyz);
}
Image img = (Image)bitmap;
Clipboard.SetImage(img);
ItsCopiedFromScreen = true;
MyBtmpToByteArr b2arr = new MyBtmpToByteArr();// inststance of My bitmap to byte[]
AAdToAppLog("start Converting Bitmap To ByteArr");// logging programs activity in a listview via reflection
MyCuptredBtmpToolBox.CuptByteArr = b2arr.Bitmap2ByteArr(bitmap);
AAdToAppLog("Done Convertion ArrSize " + b2arr.Bitmap2ByteArr(bitmap).Length + ", Resting CopyDestionation SelctdIndx");
Combo_CopyFromScrn.SelectedIndex = 0;
if (SaveIt)
{
string btmpsRefrenceSave = MyCuptredBtmpToolBox.SourceX_Cuptured.ToString() + "," + MyCuptredBtmpToolBox.SourceY_Cuptured.ToString() + "," + MyCuptredBtmpToolBox.RectWidth_Cuptured.ToString() + "," + MyCuptredBtmpToolBox.RectHeight_Cuptured.ToString() + "," + TBX_FileSaveName.Text;
if (ItsLoadedFromFile)
{
File.WriteAllBytes(initDir + TBX_FileSaveName.Text, b2arr.Bitmap2ByteArr(bitmap));// See next block Method Bitmap2ByteArr method
File.WriteAllText(initDir + TBX_FileSaveName.Text.Replace("bar", "txt"), btmpsRefrenceSave);
}
else
{
File.WriteAllBytes(initDir + TBX_FileSaveName.Text + ExtBar, b2arr.Bitmap2ByteArr(bitmap));
File.WriteAllText(initDir + TBX_FileSaveName.Text.Replace("bar", "txt") + ExtTXT, btmpsRefrenceSave);
}
//MyCuptredBtmpToolBox.CupturedStaticBmp.Save(MyCuptredBtmpToolBox.FnameToSave.Replace(".bar", ".") + ExtJpg, ImageFormat.Jpeg);
bitmap.Save(initDir + TBX_FileSaveName.Text + ExtJpg, ImageFormat.Jpeg);
}
if (DoCompare)
{
AAdToAppLog("starting Compare " + Fname +" With Btmp2Arr From Screen");
R_ComparwByteArrClass tstCmp = new R_ComparwByteArrClass();
if (itsAutomated)
{
CompareByt2Btmp = R_ComparwByteArrClass.ByteArrCompare(DoAutoLoadCuptByteArr(initDir, Fname + ExtBar), b2arr.Bitmap2ByteArr(bitmap));
}
else
{
CompareByt2Btmp = R_ComparwByteArrClass.ByteArrCompare(MyLoadedBtmpToolBox.LoadedByteArr, b2arr.Bitmap2ByteArr(bitmap));
}
bring(MyApp);
AAdToAppLog(CompareByt2Btmp.ToString());
}
}
}
将位图转换为 ByteArr 类以及将捕获的 btmp 转换为 byte[] 的方法
public class MyBtmpToByteArr
{
public byte[] Bitmap2ByteArr(Bitmap btmpToConvertintoByteArr)
{
//Convert image to a byte array
System.Drawing.ImageConverter MyImgCvrtr = new System.Drawing.ImageConverter();
byte[] btImage = new byte[1];
btImage = (byte[])MyImgCvrtr.ConvertTo(btmpToConvertintoByteArr, btImage.GetType());
return btImage;
}
}
但是如果位置改变了,即使我在屏幕上给出了图像的新位置,我也无法识别它,但当我进行测试时,使用绘画并打开网格,我定位了相同裁剪的两个副本图像,我成功了,但在一个真实场景中,游戏屏幕有几个图标共享背景,我尝试将它们相互比较,但没有成功 即使我给出了位置,是否有一个小于像素的单位,也许游戏的图形使用的单位是像素的一小部分?或者也许是其他单位 我的给定位置 Point1 是第一个图标的 X100 Y100 ,而另一个不是在 200,200 中,实际上是在 200.33、200.55 左右......这就是为什么我没有得到死锁位置/位置? p.s 我认为它使用的是 diretx,如果不是,它在 openGL 上,如果它对用于定位图像的单位很重要,最确定在 Directx 上是否存在小于像素的单位......并且常用? 如果不是,您将如何实现一个从 x100 到 x150 和 y100 到 y150 循环的函数,以便我可以搜索图像
【问题讨论】:
-
不要认为有任何比像素更小的东西,它尽可能小,但它可能是其他一些单位,比如“点”。
标签: c# bitmap image-comparison