public static Bitmap recoverScreenBitmapXOR(List <ShortRec> difPoints, Bitmap globalBtm, Bitmap difBtm) { Bitmap toBtm = (Bitmap)globalBtm.Clone();//克隆一份,保证不冲突访问 PixelFormat pf = PixelFormat.Format24bppRgb; BitmapData bd1 = difBtm.LockBits(new Rectangle(0, 0, difBtm.Width, difBtm.Height), ImageLockMode.ReadOnly, pf); BitmapData bd2 = toBtm.LockBits(new Rectangle(0, 0, toBtm.Width, toBtm.Height), ImageLockMode.WriteOnly, pf); try { unsafe { foreach (ShortRec difPoint in difPoints) { int startX = difPoint.xPoint; int startY = difPoint.yPoint; int width = difPoint.width; int height = difPoint.height; byte *p1 = (byte *)bd1.Scan0 + startY * bd1.Stride; byte *p2 = (byte *)bd2.Scan0 + startY * bd2.Stride; //按块大小进行扫描不同数据 for (int i = 0; i < width; i += 1) { int wi = startX + i; if (wi >= bd1.Width || wi >= bd2.Width) { break; } for (int j = 0; j < height; j += 1) { int hj = startY + j; if (hj >= bd1.Height || hj >= bd2.Height) { break; } ICColor *pc1 = (ICColor *)(p1 + wi * 3 + bd1.Stride * j); ICColor *pc2 = (ICColor *)(p2 + wi * 3 + bd2.Stride * j); pc2->R ^= pc1->R; pc2->G ^= pc1->G; pc2->B ^= pc1->B; } } } } } finally { difBtm.UnlockBits(bd1); toBtm.UnlockBits(bd2); } return(toBtm); }
public static void scanBitmap(Bitmap fromBtm) { // Bitmap fromBtm = (Bitmap)fromBtmOrl.Clone();//克隆一份,保证不冲突访问 BitmapData bd1 = fromBtm.LockBits(new Rectangle(0, 0, fromBtm.Width, fromBtm.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); try { unsafe { byte *p1 = (byte *)bd1.Scan0 + 0 * bd1.Stride; //按块大小进行扫描不同数据 for (int i = 0; i < fromBtm.Width; i += 3) { for (int j = 0; j < fromBtm.Height; j += 3) { ICColor *pc1 = (ICColor *)(p1 + i * 3 + bd1.Stride * j); pc1->R = pc1->R; pc1->G = pc1->G; pc1->B = pc1->B; } } } } finally { fromBtm.UnlockBits(bd1); } }
/**根据开始点的坐标,扣取不同的图形块*/ public static Bitmap getBlocksIn1Bitmap(List <ShortRec> difPoints, Bitmap fromBtmOrl) { Bitmap fromBtm = (Bitmap)fromBtmOrl.Clone();//克隆一份,保证不冲突访问 Bitmap ret = new Bitmap(fromBtmOrl.Width, fromBtmOrl.Height, PixelFormat.Format24bppRgb); Bitmap ret2 = new Bitmap(fromBtmOrl.Width, fromBtmOrl.Height, PixelFormat.Format24bppRgb); PixelFormat pf = PixelFormat.Format24bppRgb; BitmapData bd1 = fromBtm.LockBits(new Rectangle(0, 0, fromBtm.Width, fromBtm.Height), ImageLockMode.ReadOnly, pf); BitmapData bd2 = ret.LockBits(new Rectangle(0, 0, ret.Width, ret.Height), ImageLockMode.WriteOnly, pf); try { unsafe { foreach (ShortRec difPoint in difPoints) { int startX = difPoint.xPoint; int startY = difPoint.yPoint; int width = difPoint.width; int height = difPoint.height; byte *p1 = (byte *)bd1.Scan0 + startY * bd1.Stride; byte *p2 = (byte *)bd2.Scan0 + startY * bd2.Stride; //按块大小进行扫描不同数据 for (int i = 0; i < width; i += 1) { int wi = startX + i; if (wi >= bd1.Width || wi >= bd2.Width) { break; } for (int j = 0; j < height; j += 1) { int hj = startY + j; if (hj >= bd1.Height || hj >= bd2.Height) { break; } ICColor *pc1 = (ICColor *)(p1 + wi * 3 + bd1.Stride * j); ICColor *pc2 = (ICColor *)(p2 + wi * 3 + bd2.Stride * j); pc2->R = pc1->R; pc2->G = pc1->G; pc2->B = pc1->B; } } } } } finally { ret.UnlockBits(bd1); fromBtm.UnlockBits(bd2); } return(ret); }
/// <summary> /// 比较两个图像 /// </summary> /// <param name="bmp1"></param> /// <param name="bmp2"></param> /// <param name="margin"></param> /// <returns></returns> private static List <Point> PicRgbCompare(Bitmap bmp1, Bitmap bmp2, Rectangle range, int OutRgb = 500000) { // 戻り値 List <Point> rects = new List <Point>(); // 比較範囲RGB取得 BitmapData bd1 = bmp1.LockBits(range, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); BitmapData bd2 = bmp2.LockBits(range, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); try { unsafe { int w = 0, h = 0; while (h < bd1.Height && h < bd2.Height) { byte *p1 = (byte *)bd1.Scan0 + h * bd1.Stride; byte *p2 = (byte *)bd2.Scan0 + h * bd2.Stride; w = 0; while (w < bd1.Width && w < bd2.Width) { if (w >= bd1.Width || w >= bd2.Width) { break; } if (h >= bd1.Height || h >= bd2.Height) { break; } ICColor *pc1 = (ICColor *)(p1 + w * 3); ICColor *pc2 = (ICColor *)(p2 + w * 3); if (pc1->R != pc2->R || pc1->G != pc2->G || pc1->B != pc2->B) { //当前块有某个象素点颜色值不相同.也就是有差异. int bw = Math.Min(1, bd1.Width - w); int bh = Math.Min(1, bd1.Height - h); rects.Add(new Point(w + range.Left, h + range.Top)); if (rects.Count > OutRgb) { return(null); } goto E; } E: w++; } h++; } } } finally { bmp1.UnlockBits(bd1); bmp2.UnlockBits(bd2); } return(rects); }
private static int SCANSTRIDE = 2; //隔行扫描,每隔3行/列,扫描一次 /// <summary> /// 比较两个图像 /// </summary> /// <param name="bmp1"></param> /// <param name="bmp2"></param> /// <param name="block"></param> /// <returns></returns> /// public static List <ShortRec> Compare(Rectangle[] dirtyRecs, Bitmap globalBtm, Bitmap lastFrame, Size block) { // if (globalBtm.Size != lastFrame.Size) return null; List <ShortRec> difPoint = new List <ShortRec>(); PixelFormat pf = PixelFormat.Format32bppArgb; Bitmap retBtm = new Bitmap(lastFrame.Width, lastFrame.Height, lastFrame.PixelFormat); Graphics g = Graphics.FromImage(retBtm); BitmapData bd1 = globalBtm.LockBits(new Rectangle(0, 0, globalBtm.Width, globalBtm.Height), ImageLockMode.ReadOnly, pf); BitmapData bd2 = lastFrame.LockBits(new Rectangle(0, 0, lastFrame.Width, lastFrame.Height), ImageLockMode.ReadOnly, pf); try { unsafe { /* * foreach (Rectangle dirRec in dirtyRecs) * { * //新图形坐标 * int startX = dirRec.Left; * int startY = dirRec.Top; * int width = dirRec.Width; * int height = dirRec.Height; * int endX = dirRec.Right; * int endY = dirRec.Bottom; * int w = startX, h = startY; * int start = new Random().Next(0, SCANSTRIDE); * while (h < endY) * { * byte* p1 = (byte*)bd1.Scan0 + h * bd1.Stride; * byte* p2 = (byte*)bd2.Scan0 + h * bd2.Stride; * w = startX; * while (w < endX) * { * for (int j = start; j < block.Height; j += SCANSTRIDE) * { * int hj = h + j; * if (hj >= endY) break; * byte* pc1 = p1 + j * bd1.Stride + w * 4; * byte* pc2 = p2 + j * bd1.Stride + w * 4; * if (memcmp(pc1, pc2, Math.Min(block.Width, endX - w) * 4) != 0) * { * int bw = Math.Min(block.Width, endX - w); * int bh = Math.Min(block.Height, endY - h); * difPoint.Add(new ShortRec(w, h, bw, bh)); * break; * } * } * w += block.Width; * } * h += block.Height; * * } * }*/ foreach (Rectangle dirRec in dirtyRecs) { //新图形坐标 int startX = dirRec.Left; int startY = dirRec.Top; int width = dirRec.Width; int height = dirRec.Height; int endX = dirRec.Right; int endY = dirRec.Bottom; int w = startX, h = startY; int start = new Random().Next(0, SCANSTRIDE);//确定随机监测点,保证随机探测 while (h < endY) { byte *p1 = (byte *)bd1.Scan0 + h * bd1.Stride; byte *p2 = (byte *)bd2.Scan0 + h * bd2.Stride; w = startX; while (w < endX) { //按块大小进行扫描 for (int i = start; i < block.Width; i += SCANSTRIDE) { int wi = w + i; if (wi >= endX) { break; } for (int j = start; j < block.Height; j += SCANSTRIDE) { int hj = h + j; if (hj >= endY) { break; } ICColor *pc1 = (ICColor *)(p1 + wi * 4 + bd1.Stride * j); ICColor *pc2 = (ICColor *)(p2 + wi * 4 + bd2.Stride * j); //忽略A值 if (Math.Abs(pc1->R - pc2->R) > BOTTOMLINE || Math.Abs(pc1->G - pc2->G) > BOTTOMLINE || Math.Abs(pc1->B - pc2->B) > BOTTOMLINE) { int bw = Math.Min(block.Width, endX - w); int bh = Math.Min(block.Height, endY - h); difPoint.Add(new ShortRec(w, h, bw, bh)); //可以继续使用clone() //bmp1.Clone(new Rectangle(w, h, 19, 19), bmp1.PixelFormat).Save("D:\\test.jpeg", ImageFormat.Jpeg); goto E; } //SCANSTRIDE = (j & 3) + 1; } //SCANSTRIDE = 3 - (i % 3); } E: w += block.Width; } h += block.Height; } } } } finally { globalBtm.UnlockBits(bd1); lastFrame.UnlockBits(bd2); } return(difPoint); }
private static int SCANSTRIDE = 3; //隔行扫描,每隔3行/列,扫描一次 /// <summary> /// 比较两个图像 /// </summary> /// <param name="bmp1"></param> /// <param name="bmp2"></param> /// <param name="block"></param> /// <returns></returns> /// public static List <Rectangle> Compare(Bitmap bmp1, Bitmap bmp2, Size block) { MemoryStream bitBytes = new MemoryStream(); List <Rectangle> rects = new List <Rectangle>(); PixelFormat pf = PixelFormat.Format24bppRgb; Bitmap retBitmap = new Bitmap(bmp2.Size.Width, bmp2.Size.Height, PixelFormat.Format24bppRgb); BitmapData bd1 = bmp1.LockBits(new Rectangle(0, 0, bmp1.Width, bmp1.Height), ImageLockMode.ReadOnly, pf); BitmapData bd2 = bmp2.LockBits(new Rectangle(0, 0, bmp2.Width, bmp2.Height), ImageLockMode.ReadOnly, pf); BitmapData bd3 = retBitmap.LockBits(new Rectangle(0, 0, retBitmap.Width, retBitmap.Height), ImageLockMode.WriteOnly, pf); try { unsafe { int w = 0, h = 0; int start = new Random().Next(0, SCANSTRIDE); //确定随机监测点,保证随机探测 while (h < bd1.Height && h < bd2.Height) { byte *p1 = (byte *)bd1.Scan0 + h * bd1.Stride;//bd1.Stride为一行的像素个数*3+padding=width*3+padding(字节数) byte *p2 = (byte *)bd2.Scan0 + h * bd2.Stride; byte *p3 = (byte *)bd3.Scan0 + h * bd3.Stride; w = 0; while (w < bd1.Width && w < bd2.Width) { //按块大小进行扫描 for (int i = start; i < block.Width; i += SCANSTRIDE) { int wi = w + i; if (wi >= bd1.Width || wi >= bd2.Width) { break; } for (int j = start; j < block.Height; j += SCANSTRIDE) { int hj = h + j; if (hj >= bd1.Height || hj >= bd2.Height) { break; } ICColor *pc1 = (ICColor *)(p1 + wi * 3 + bd1.Stride * j); ICColor *pc2 = (ICColor *)(p2 + wi * 3 + bd2.Stride * j); // ICColor* pc3 = (ICColor*)(p3 + wi * 3 + bd3.Stride * j); //if (pc1->R != pc2->R || pc1->G != pc2->G || pc1->B != pc2->B) if (Math.Abs(pc1->R - pc2->R) > BOTTOMLINE || Math.Abs(pc1->G - pc2->G) > BOTTOMLINE || Math.Abs(pc1->B - pc2->B) > BOTTOMLINE) { //当前块有某个象素点颜色值不相同.也就是有差异. /** * pc3->R = pc2->R; * pc3->G = pc2->G; * pc3->B = pc2->B; */ int bw = Math.Min(block.Width, bd1.Width - w); int bh = Math.Min(block.Height, bd1.Height - h); rects.Add(new Rectangle(w, h, bw, bh)); /************************************************************************/ //内存直接提取数据 /***********************************************************************/ /* bitBytes.WriteByte((byte)w); * bitBytes.WriteByte((byte)(w >> 8)); * bitBytes.WriteByte((byte)h); * bitBytes.WriteByte((byte)(h >> 8)); * bitBytes.WriteByte((byte)bw); * bitBytes.WriteByte((byte)(bw >> 8)); * bitBytes.WriteByte((byte)bh); * bitBytes.WriteByte((byte)(bh >> 8)); * * */ /* * 自定义数据压缩算法,保证数据量最少 */ /* * byte Rtemp=0, Gtemp=0, Btemp=0; * bool isFirst = true; * int sameTimes = 0; * * for (int i2 = 0; i2 < block.Width; i2 += 1) * { * int wi2 = w + i2; * if (wi2 >= bd1.Width || wi2 >= bd2.Width) break; * * for (int j2 = 0; j2 < block.Height; j2 += 1) * { * int hj2 = h + j2; * if (hj2 >= bd1.Height || hj2 >= bd2.Height) break; * * ICColor* pc3 = (ICColor*)(p3 + wi2 * 3 + bd3.Stride * j2); * ICColor* pc22 = (ICColor*)(p2 + wi2 * 3 + bd2.Stride * j2); * pc3->R=pc22->R; * pc3->G=pc22->G; * pc3->B=pc22->B; * /* * if (isFirst) * { * isFirst = false; * Rtemp = pc22->R; * Gtemp = pc22->G; * Btemp = pc22->B; * bitBytes.WriteByte(pc3->R); * bitBytes.WriteByte(pc3->G); * bitBytes.WriteByte(pc3->B); * sameTimes++; * continue; * * } * * if (Math.Abs(Rtemp - pc22->R) > BOTTOMLINE || Math.Abs(Gtemp - pc22->G) > BOTTOMLINE || Math.Abs(Btemp - pc22->B) > BOTTOMLINE) * { * bitBytes.WriteByte((byte)sameTimes); * bitBytes.WriteByte((byte)(sameTimes >> 8)); * bitBytes.WriteByte(pc22->R); * bitBytes.WriteByte(pc22->G); * bitBytes.WriteByte(pc22->B); * Rtemp = pc22->R; * Gtemp = pc22->G; * Btemp = pc22->B; * sameTimes = -1; * * } * * sameTimes++; */ // } //} goto E; } } } E: w += block.Width; } h += block.Height; } } } finally { bmp1.UnlockBits(bd1); bmp2.UnlockBits(bd2); retBitmap.UnlockBits(bd3); } /* retBitmap.Save("D:\\test.jpeg", ImageFormat.Jpeg); * MemoryStream msIzip = new MemoryStream(); * MemoryStream ms = new MemoryStream(); * retBitmap.Save(ms, ImageFormat.Jpeg); * * * ZipOutputStream outZip = new ZipOutputStream(msIzip); * outZip.SetLevel(9); * outZip.PutNextEntry(new ZipEntry("T")); * outZip.Write(ms.ToArray(), 0, (int)ms.Length); * outZip.Close(); * msIzip.Close(); * // outZip.Write(bitBytes.ToArray(), 0, (int)bitBytes.Length); * * * MemoryStream ms2 = new MemoryStream(); * GZipStream zip = new GZipStream(ms2, CompressionMode.Compress); * zip.Write(bitBytes.ToArray(), 0, (int)bitBytes.Length); * zip.Close(); * ms2.Close(); * MessageBox.Show("jpeg:" + ms.Length + "Bitbytes:" + bitBytes.Length + "zip:" + ms2.ToArray().Length + "Izip:" + msIzip.ToArray().Length); */ return(rects); }
/**根据开始点的坐标,扣取不同的图形块*/ public static Bitmap getBlocksIn1Bitmap(List <Rectangle> difPoints, Bitmap fromBtmOrl, Bitmap globalBtmOrl, Size block) { Bitmap fromBtm = (Bitmap)fromBtmOrl.Clone();//克隆一份,保证不冲突访问 Bitmap globalBtm = (Bitmap)globalBtmOrl.Clone(); Bitmap ret = new Bitmap(fromBtmOrl.Width, fromBtmOrl.Height, PixelFormat.Format24bppRgb); PixelFormat pf = PixelFormat.Format24bppRgb; BitmapData bd0 = globalBtm.LockBits(new Rectangle(0, 0, globalBtm.Width, globalBtm.Height), ImageLockMode.ReadOnly, pf); BitmapData bd1 = fromBtm.LockBits(new Rectangle(0, 0, fromBtm.Width, fromBtm.Height), ImageLockMode.ReadOnly, pf); BitmapData bd2 = ret.LockBits(new Rectangle(0, 0, ret.Width, ret.Height), ImageLockMode.WriteOnly, pf); try { unsafe { foreach (Rectangle difPoint in difPoints) { int startX = difPoint.Left; int startY = difPoint.Top; byte *p0 = (byte *)bd0.Scan0 + startY * bd0.Stride; byte *p1 = (byte *)bd1.Scan0 + startY * bd1.Stride; byte *p2 = (byte *)bd2.Scan0 + startY * bd2.Stride; //按块大小进行扫描不同数据 for (int i = 0; i < block.Width; i += 1) { int wi = startX + i; if (wi >= bd1.Width || wi >= bd2.Width) { break; } for (int j = 0; j < block.Height; j += 1) { int hj = startY + j; if (hj >= bd1.Height || hj >= bd2.Height) { break; } ICColor *pc0 = (ICColor *)(p0 + wi * 3 + bd0.Stride * j); ICColor *pc1 = (ICColor *)(p1 + wi * 3 + bd1.Stride * j); ICColor *pc2 = (ICColor *)(p2 + wi * 3 + bd2.Stride * j); pc2->R = (byte)(pc1->R ^ pc0->R); pc2->G = (byte)(pc1->G ^ pc0->G); pc2->B = (byte)(pc1->B ^ pc0->B); } } } } } finally { ret.UnlockBits(bd1); fromBtm.UnlockBits(bd2); globalBtm.UnlockBits(bd0); } return(ret); }
/// <summary> /// 比较两个图像 /// </summary> /// <param name="bmp1"></param> /// <param name="bmp2"></param> /// <param name="block"></param> /// <returns></returns> public static List <Rectangle> Compare(Bitmap bmp1, Bitmap bmp2, Size block) { List <Rectangle> rects = new List <Rectangle>(); PixelFormat pf = PixelFormat.Format24bppRgb; BitmapData bd1 = bmp1.LockBits(new Rectangle(0, 0, bmp1.Width, bmp1.Height), ImageLockMode.ReadOnly, pf); BitmapData bd2 = bmp2.LockBits(new Rectangle(0, 0, bmp2.Width, bmp2.Height), ImageLockMode.ReadOnly, pf); try { unsafe { int w = 0, h = 0; while (h < bd1.Height && h < bd2.Height) { byte *p1 = (byte *)bd1.Scan0 + h * bd1.Stride; byte *p2 = (byte *)bd2.Scan0 + h * bd2.Stride; w = 0; while (w < bd1.Width && w < bd2.Width) { //按块大小进行扫描 for (int i = 0; i < block.Width; i++) { int wi = w + i; if (wi >= bd1.Width || wi >= bd2.Width) { break; } for (int j = 0; j < block.Height; j++) { int hj = h + j; if (hj >= bd1.Height || hj >= bd2.Height) { break; } ICColor *pc1 = (ICColor *)(p1 + wi * 3 + bd1.Stride * j); ICColor *pc2 = (ICColor *)(p2 + wi * 3 + bd2.Stride * j); if (pc1->R != pc2->R || pc1->G != pc2->G || pc1->B != pc2->B) { //当前块有某个象素点颜色值不相同.也就是有差异. int bw = Math.Min(block.Width, bd1.Width - w); int bh = Math.Min(block.Height, bd1.Height - h); rects.Add(new Rectangle(w, h, bw, bh)); goto E; } } } E: w += block.Width; } h += block.Height; } } } finally { bmp1.UnlockBits(bd1); bmp2.UnlockBits(bd2); } return(rects); }
private static Point FindPointImpl(Bitmap bitmap, out Point comboPoint) { var standPColor = Color.FromArgb(54, 60, 102); var comboPColor = Color.FromArgb(245, 245, 245); Point standPoint = Point.Empty; comboPoint = Point.Empty; int y1 = (int)(bitmap.Height * 0.2); int y2 = (int)(bitmap.Height * 0.63); PixelFormat pf = PixelFormat.Format24bppRgb; BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, y1, bitmap.Width, y2), ImageLockMode.ReadOnly, pf); try { unsafe { int w = 0; while (y2 > y1) { byte *p = (byte *)bitmapData.Scan0 + (y2 - y1 - 1) * bitmapData.Stride; w = bitmap.Width; int endColorCount = 0; while (w > 40) { ICColor *pc = (ICColor *)(p + w * 3); if (standPoint == Point.Empty && pc->R == standPColor.R && pc->G == standPColor.G && pc->B == standPColor.B) { standPoint = new Point(w - 3, y2); if (comboPoint != Point.Empty) { break; } } else if (comboPoint == Point.Empty) { if (pc->R == comboPColor.R && pc->G == comboPColor.G && pc->B == comboPColor.B) { endColorCount++; } else { if (endColorCount > 0) { comboPoint = new Point(w + 5, y2 - 1); if (standPoint != Point.Empty) { break; } } endColorCount = 0; } } w--; } if (comboPoint == Point.Empty) { if (endColorCount > 10) { comboPoint = new Point(w + 5, y2 - 1); } } if (standPoint != Point.Empty && comboPoint != Point.Empty) { break; } y2--; } } return(standPoint); } finally { bitmap.UnlockBits(bitmapData); } }
/// <summary> /// 比较两个图像 /// </summary> /// <param name="bmp1">图片1</param> /// <param name="bmp2">图片2</param> /// <returns>相同的部分</returns> public static List <Rectangle> Compare(Bitmap bmp1, Bitmap bmp2) { List <Rectangle> rects = new List <Rectangle>(); PixelFormat pf = PixelFormat.Format24bppRgb; BitmapData bd1 = bmp1.LockBits(new Rectangle(0, 0, bmp1.Width, bmp1.Height), ImageLockMode.ReadOnly, pf); BitmapData bd2 = bmp2.LockBits(new Rectangle(0, 0, bmp2.Width, bmp2.Height), ImageLockMode.ReadOnly, pf); Size block = new Size(bd1.Width, bd1.Height); try { unsafe { int startX = 0, startY = 0; while (startX <= block.Width) { while (startY <= block.Height) { int w = startX, h = startY; while (h < bd2.Height && h + block.Height <= bd2.Height) { byte *p1 = (byte *)bd1.Scan0; byte *p2 = (byte *)bd2.Scan0 + h * bd2.Stride; w = startX; while (w < bd2.Width && w + block.Width <= bd2.Width) { bool result = true; //按块大小进行扫描 for (int i = 0; i < block.Width; i++) { int wi = w + i; if (wi >= bd2.Width) { break; } for (int j = 0; j < block.Height; j++) { int hj = h + j; if (hj >= bd2.Height) { break; } ICColor *pc1 = (ICColor *)(p1 + i * 3 + bd1.Stride * j); ICColor *pc2 = (ICColor *)(p2 + wi * 3 + bd2.Stride * j); if (pc1->R != pc2->R || pc1->G != pc2->G || pc1->B != pc2->B) { result = false; break; } } if (!result) { break; } } if (result) { rects.Add(new Rectangle(w, h, block.Width, block.Height)); } E: w += block.Width; } h += block.Height; } startY++; } startX++; startY = 1; } } } finally { bmp1.UnlockBits(bd1); bmp2.UnlockBits(bd2); } return(rects); }
private static int SCANSTRIDE = 2; //隔行扫描,每隔3行/列,扫描一次 /// <summary> /// 比较两个图像 /// </summary> /// <param name="bmp1"></param> /// <param name="bmp2"></param> /// <param name="block"></param> /// <returns></returns> /// public static List <ShortRec> Compare(Bitmap bmp1, Bitmap bmp2, Size block) { List <ShortRec> rects = new List <ShortRec>(); PixelFormat pf = PixelFormat.Format24bppRgb; BitmapData bd1 = bmp1.LockBits(new Rectangle(0, 0, bmp1.Width, bmp1.Height), ImageLockMode.ReadOnly, pf); BitmapData bd2 = bmp2.LockBits(new Rectangle(0, 0, bmp2.Width, bmp2.Height), ImageLockMode.ReadOnly, pf); try { unsafe { /* * int w = 0, h = 0; * int start = new Random().Next(0, SCANSTRIDE); * while (h < bd1.Height && h < bd2.Height) * { * byte* p1 = (byte*)bd1.Scan0 + h * bd1.Stride; * byte* p2 = (byte*)bd2.Scan0 + h * bd2.Stride; * w = 0; * while (w < bd1.Width && w < bd2.Width) * { * for (int j = start; j < block.Height; j += SCANSTRIDE) * { * int hj = h + j; * if (hj >= bd1.Height || hj >= bd2.Height) break; * * byte* pc1 = p1 + j * bd1.Stride + w * 3; * byte* pc2 = p2 + j * bd1.Stride + w * 3; * if (memcmp(pc1, pc2, Math.Min(block.Width, bd1.Width - w) * 4) != 0) * { * int bw = Math.Min(block.Width, bd1.Width - w); * int bh = Math.Min(block.Height, bd1.Width - h); * rects.Add(new ShortRec(w, h, bw, bh)); * break; * } * * } * w += block.Width; * } * * * h += block.Height; * } * */ int w = 0, h = 0; int start = new Random().Next(0, SCANSTRIDE);//确定随机监测点,保证随机探测 while (h < bd1.Height && h < bd2.Height) { byte *p1 = (byte *)bd1.Scan0 + h * bd1.Stride; byte *p2 = (byte *)bd2.Scan0 + h * bd2.Stride; w = 0; while (w < bd1.Width && w < bd2.Width) { //按块大小进行扫描 for (int i = start; i < block.Width; i += SCANSTRIDE) { int wi = w + i; if (wi >= bd1.Width || wi >= bd2.Width) { break; } for (int j = start; j < block.Height; j += SCANSTRIDE) { int hj = h + j; if (hj >= bd1.Height || hj >= bd2.Height) { break; } ICColor *pc1 = (ICColor *)(p1 + wi * 3 + bd1.Stride * j); ICColor *pc2 = (ICColor *)(p2 + wi * 3 + bd2.Stride * j); //if (pc1->R != pc2->R || pc1->G != pc2->G || pc1->B != pc2->B) if (Math.Abs(pc1->R - pc2->R) > BOTTOMLINE || Math.Abs(pc1->G - pc2->G) > BOTTOMLINE || Math.Abs(pc1->B - pc2->B) > BOTTOMLINE) { int bw = Math.Min(block.Width, bd1.Width - w); int bh = Math.Min(block.Height, bd1.Height - h); rects.Add(new ShortRec(w, h, bw, bh)); goto E; } } } E: w += block.Width; } h += block.Height; } } } finally { bmp1.UnlockBits(bd1); bmp2.UnlockBits(bd2); } return(rects); }