有没有更快的方法来获取特定点的像素颜色?

时间:2019-01-15 21:41:26

标签: c#

我正在尝试以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)。

0 个答案:

没有答案