C#在另一个位图中搜索位图
我曾经尝试过开源项目,例如,但是它似乎对我根本不起作用。然后,我尝试这样编写自己的算法(目前还没有使用容差)C#在另一个位图中搜索位图,c#,image-processing,bitmap,bitmapdata,C#,Image Processing,Bitmap,Bitmapdata,我曾经尝试过开源项目,例如,但是它似乎对我根本不起作用。然后,我尝试这样编写自己的算法(目前还没有使用容差) 公共静态矩形图像搜索(位图到搜索、位图到查找、整数容差、双最小百分比){ 矩形返回值=矩形。空; BitmapData-ToSearchData=ToSearch.LockBits(新矩形(0,0,ToSearch.Width,ToSearch.Height),ImageLockMode.ReadOnly,PixelFormat.Format24bppRgb); BitmapData T
公共静态矩形图像搜索(位图到搜索、位图到查找、整数容差、双最小百分比){
矩形返回值=矩形。空;
BitmapData-ToSearchData=ToSearch.LockBits(新矩形(0,0,ToSearch.Width,ToSearch.Height),ImageLockMode.ReadOnly,PixelFormat.Format24bppRgb);
BitmapData ToFindData=ToFind.LockBits(新矩形(0,0,ToFind.Width,ToFind.Height)、ImageLockMode.ReadOnly、PixelFormat.Format24bppRgb);
IntPtr ToSearchScan0=ToSearchData.Scan0;
IntPtr ToFindScan0=ToFindData.Scan0;
int PixelWidth=3;//3,因为每像素24位格式
int-ToSearchStride=ToSearchData.Stride;
int-ToSearchPadding=ToSearchStride-(ToSearch.Width*像素宽度);
int-ToFindStride=ToFindData.Stride;
int-tofindpatting=ToFindStride-(ToFind.Width*像素宽度);
不安全{
byte*ToSearchPixelArray=(byte*)(void*)ToSearchData.Scan0;
byte*ToFindPixelArray=(byte*)(void*)ToFindData.Scan0;
字节sB、sG、sR、fB、fG、fR;
fB=ToFindPixelArray[0];
fG=ToFindPixelArray[1];
fR=ToFindPixelArray[2];
for(int sY=0;sY=最小百分比){
ReturnValue.X=(int)(sX/3);
ReturnValue.Y=sY;
ReturnValue.Width=ToFind.Width;
ReturnValue.Height=ToFind.Height;
//这是在C中中断嵌套循环的最佳方法#
sX=int.MaxValue;
sY=int.MaxValue;
}
}
}
ToSearchPixelArray+=ToSearchPadding;
}
}
ToSearch.UnlockBits(ToSearchData);
ToFind.UnlockBits(ToFindData);
返回值;
}
但即使这样也无法检测到我正在搜索的确切图像的截图。请不要建议使用Emgu之类的东西,我在商业应用程序中使用它,无法从任何GNU许可项目购买许可证(我也不是开源项目)。在“sourceBitmap”中插入许多条目“serchingBitmap”。
在这个例子中,我不使用不安全的代码
public static List<Point> FindBitmapsEntry(Bitmap sourceBitmap, Bitmap serchingBitmap)
{
#region Arguments check
if (sourceBitmap == null || serchingBitmap == null)
throw new ArgumentNullException();
if (sourceBitmap.PixelFormat != serchingBitmap.PixelFormat)
throw new ArgumentException("Pixel formats arn't equal");
if (sourceBitmap.Width < serchingBitmap.Width || sourceBitmap.Height < serchingBitmap.Height)
throw new ArgumentException("Size of serchingBitmap bigger then sourceBitmap");
#endregion
var pixelFormatSize = Image.GetPixelFormatSize(sourceBitmap.PixelFormat)/8;
// Copy sourceBitmap to byte array
var sourceBitmapData = sourceBitmap.LockBits(new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height),
ImageLockMode.ReadOnly, sourceBitmap.PixelFormat);
var sourceBitmapBytesLength = sourceBitmapData.Stride * sourceBitmap.Height;
var sourceBytes = new byte[sourceBitmapBytesLength];
Marshal.Copy(sourceBitmapData.Scan0, sourceBytes, 0, sourceBitmapBytesLength);
sourceBitmap.UnlockBits(sourceBitmapData);
// Copy serchingBitmap to byte array
var serchingBitmapData =
serchingBitmap.LockBits(new Rectangle(0, 0, serchingBitmap.Width, serchingBitmap.Height),
ImageLockMode.ReadOnly, serchingBitmap.PixelFormat);
var serchingBitmapBytesLength = serchingBitmapData.Stride * serchingBitmap.Height;
var serchingBytes = new byte[serchingBitmapBytesLength];
Marshal.Copy(serchingBitmapData.Scan0, serchingBytes, 0, serchingBitmapBytesLength);
serchingBitmap.UnlockBits(serchingBitmapData);
var pointsList = new List<Point>();
// Serching entries
// minimazing serching zone
// sourceBitmap.Height - serchingBitmap.Height + 1
for (var mainY = 0; mainY < sourceBitmap.Height - serchingBitmap.Height + 1; mainY++)
{
var sourceY = mainY * sourceBitmapData.Stride;
for (var mainX = 0; mainX < sourceBitmap.Width - serchingBitmap.Width + 1; mainX++)
{// mainY & mainX - pixel coordinates of sourceBitmap
// sourceY + sourceX = pointer in array sourceBitmap bytes
var sourceX = mainX*pixelFormatSize;
var isEqual = true;
for (var c = 0; c < pixelFormatSize; c++)
{// through the bytes in pixel
if (sourceBytes[sourceX + sourceY + c] == serchingBytes[c])
continue;
isEqual = false;
break;
}
if (!isEqual) continue;
var isStop = false;
// find fist equalation and now we go deeper)
for (var secY = 0; secY < serchingBitmap.Height; secY++)
{
var serchY = secY * serchingBitmapData.Stride;
var sourceSecY = (mainY + secY)*sourceBitmapData.Stride;
for (var secX = 0; secX < serchingBitmap.Width; secX++)
{// secX & secY - coordinates of serchingBitmap
// serchX + serchY = pointer in array serchingBitmap bytes
var serchX = secX*pixelFormatSize;
var sourceSecX = (mainX + secX)*pixelFormatSize;
for (var c = 0; c < pixelFormatSize; c++)
{// through the bytes in pixel
if (sourceBytes[sourceSecX + sourceSecY + c] == serchingBytes[serchX + serchY + c]) continue;
// not equal - abort iteration
isStop = true;
break;
}
if (isStop) break;
}
if (isStop) break;
}
if (!isStop)
{// serching bitmap is founded!!
pointsList.Add(new Point(mainX, mainY));
}
}
}
return pointsList;
}
公共静态列表FindBitmapsEntry(位图源位图、位图serchingBitmap)
{
#区域参数检查
if(sourceBitmap==null | | serchingBitmap==null)
抛出新ArgumentNullException();
if(sourceBitmap.PixelFormat!=serchingBitmap.PixelFormat)
抛出新的ArgumentException(“像素格式不相等”);
if(sourceBitmap.Widthpublic static List<Point> FindBitmapsEntry(Bitmap sourceBitmap, Bitmap serchingBitmap)
{
#region Arguments check
if (sourceBitmap == null || serchingBitmap == null)
throw new ArgumentNullException();
if (sourceBitmap.PixelFormat != serchingBitmap.PixelFormat)
throw new ArgumentException("Pixel formats arn't equal");
if (sourceBitmap.Width < serchingBitmap.Width || sourceBitmap.Height < serchingBitmap.Height)
throw new ArgumentException("Size of serchingBitmap bigger then sourceBitmap");
#endregion
var pixelFormatSize = Image.GetPixelFormatSize(sourceBitmap.PixelFormat)/8;
// Copy sourceBitmap to byte array
var sourceBitmapData = sourceBitmap.LockBits(new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height),
ImageLockMode.ReadOnly, sourceBitmap.PixelFormat);
var sourceBitmapBytesLength = sourceBitmapData.Stride * sourceBitmap.Height;
var sourceBytes = new byte[sourceBitmapBytesLength];
Marshal.Copy(sourceBitmapData.Scan0, sourceBytes, 0, sourceBitmapBytesLength);
sourceBitmap.UnlockBits(sourceBitmapData);
// Copy serchingBitmap to byte array
var serchingBitmapData =
serchingBitmap.LockBits(new Rectangle(0, 0, serchingBitmap.Width, serchingBitmap.Height),
ImageLockMode.ReadOnly, serchingBitmap.PixelFormat);
var serchingBitmapBytesLength = serchingBitmapData.Stride * serchingBitmap.Height;
var serchingBytes = new byte[serchingBitmapBytesLength];
Marshal.Copy(serchingBitmapData.Scan0, serchingBytes, 0, serchingBitmapBytesLength);
serchingBitmap.UnlockBits(serchingBitmapData);
var pointsList = new List<Point>();
// Serching entries
// minimazing serching zone
// sourceBitmap.Height - serchingBitmap.Height + 1
for (var mainY = 0; mainY < sourceBitmap.Height - serchingBitmap.Height + 1; mainY++)
{
var sourceY = mainY * sourceBitmapData.Stride;
for (var mainX = 0; mainX < sourceBitmap.Width - serchingBitmap.Width + 1; mainX++)
{// mainY & mainX - pixel coordinates of sourceBitmap
// sourceY + sourceX = pointer in array sourceBitmap bytes
var sourceX = mainX*pixelFormatSize;
var isEqual = true;
for (var c = 0; c < pixelFormatSize; c++)
{// through the bytes in pixel
if (sourceBytes[sourceX + sourceY + c] == serchingBytes[c])
continue;
isEqual = false;
break;
}
if (!isEqual) continue;
var isStop = false;
// find fist equalation and now we go deeper)
for (var secY = 0; secY < serchingBitmap.Height; secY++)
{
var serchY = secY * serchingBitmapData.Stride;
var sourceSecY = (mainY + secY)*sourceBitmapData.Stride;
for (var secX = 0; secX < serchingBitmap.Width; secX++)
{// secX & secY - coordinates of serchingBitmap
// serchX + serchY = pointer in array serchingBitmap bytes
var serchX = secX*pixelFormatSize;
var sourceSecX = (mainX + secX)*pixelFormatSize;
for (var c = 0; c < pixelFormatSize; c++)
{// through the bytes in pixel
if (sourceBytes[sourceSecX + sourceSecY + c] == serchingBytes[serchX + serchY + c]) continue;
// not equal - abort iteration
isStop = true;
break;
}
if (isStop) break;
}
if (isStop) break;
}
if (!isStop)
{// serching bitmap is founded!!
pointsList.Add(new Point(mainX, mainY));
}
}
}
return pointsList;
}