我正在尝试以C#形式重新创建this。
我到处都使用了混合功能,以使该项目的不同部分正常工作。
我已经加载了一个带有简单文件对话框/按钮/图片框的图像,现在我将其与旧的R:240,G:240,B:240窗口形成灰色,直到生成矩形为止从染色体上。我已经对染色体进行了编码,现在我正在努力获得比分。
但是,花费了将近一个小时才能获得所有255 * 255 * 2点的像素颜色。我怀疑这与GetColorAt()
和screenPixel位图有关。这是我用来GetColorAt()
分的代码:
[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
public static extern int BitBlt(IntPtr hDC, int x, int y, int nWidth, int nHeight, IntPtr hSrcDC, int xSrc, int ySrc, int dwRop);
private static Bitmap screenPixel = new Bitmap(1, 1, PixelFormat.Format32bppArgb);
public static Color GetColorAt(Point location) {
using (Graphics gdest = Graphics.FromImage(screenPixel)) {
using (Graphics gsrc = Graphics.FromHwnd(IntPtr.Zero)) {
IntPtr hSrcDC = gsrc.GetHdc();
IntPtr hDC = gdest.GetHdc();
int retval = BitBlt(hDC, 0, 0, 1, 1, hSrcDC, location.X, location.Y, (int)CopyPixelOperation.SourceCopy);
gdest.ReleaseHdc();
gsrc.ReleaseHdc();
}
}
return screenPixel.GetPixel(0, 0);
}
然后在这里我得到目标的颜色和生成的图像,将颜色存储在数组中,然后计算它们之间的距离,并在距离数组中存储数组每个索引的距离(以及控制台调试只是为了确保其仍在运行)
double[,] distanceArray = new double[255, 255];
Color[,] generatedColorArray = new Color[255, 255];
Color[,] targetColorArray = new Color[255,255];
for (int x = 0; x < 255; x++) {
for (int y = 0; y < 255; y++) {
generatedColorArray[x, y] = GetColorAt(new Point(GetZeroZero().X + 300 + x, GetZeroZero().Y + y));
targetColorArray[x, y] = GetColorAt(new Point(GetZeroZero().X + x, GetZeroZero().Y + y));
distanceArray[x,y] = ColorDistance(targetColorArray[x, y], generatedColorArray[x, y]);
Console.WriteLine("X" + x + "Y" + y + "target" + targetColorArray[x,y]+"generated"+generatedColorArray[x,y]);
}
}
和GetZeroZero()
将查找表格的0,0,因为GetColorAt()
在屏幕坐标上起作用。现在看,我发现GetZeroZero()
被称为很多,这可能与它的运行速度有关。我找不到一种方法来专门在窗体窗口中获取像素的颜色,也找不到一种方法来使GetColorAt()
仅适用于项目的窗体窗口。
public Point GetZeroZero() {
Rectangle clientArea = RectangleToScreen(this.ClientRectangle);
int titleBarHeight = clientArea.Top - this.Top;
int leftBorderWidth = clientArea.Left - this.Left;
Point zz = new Point(this.Left + leftBorderWidth, this.Top + titleBarHeight);
return zz;
}
public static double ColorDistance(Color c1, Color c2) {
long rmean = ((long)c1.R + (long)c2.R) / 2;
long r = (long)c1.R - (long)c2.R;
long g = (long)c1.G - (long)c2.G;
long b = (long)c1.B - (long)c2.B;
return Math.Sqrt((((512 + rmean) * r * r) >> 8) + 4 * g * g + (((767 - rmean) * b * b) >> 8));
}
我希望“扫描”或GetColorAt()
图像需要一两分钟,即每秒约1000像素,但似乎每分钟接近1000像素,并且需要近一个小时扫描全部。
足够有趣的是,要花费几分之一秒的时间来计算生成的图像的平均得分(总计65025)。