5

画面から特定のピクセル座標を見つけたい。これが私のコードです(私はメガスーパー初心者です。今日はC#から始めました:

static string GetPixel(int X, int Y)
{
    Point position = new Point(X, Y);
    var bitmap = new Bitmap(1, 1);
    var graphics = Graphics.FromImage(bitmap);

    graphics.CopyFromScreen(position, new Point(0, 0), new Size(1, 1));

    var _Pixel = bitmap.GetPixel(0, 0);
    return "0x" + _Pixel.ToArgb().ToString("x").ToUpper().Remove(0, 2);
    //it returns a pixel color in a form of "0xFFFFFF" hex code
    //I had NO idea how to convert it to hex code so I did that :P
}

static void Main()
{
    // for x = 1 to screen width...
    for (int x = 1; x <= Screen.PrimaryScreen.Bounds.Bottom; x++)
    {
        // for x = 1 and y = 1 to screen height...
        for (int y = 1; y <= Screen.PrimaryScreen.Bounds.Height; y++)
        {
            string pixel = GetPixel(x, y);
            if (pixel == "0x007ACC") //blue color
            {
                MessageBox.Show("Found 0x007ACC at: (" + x + "," + y + ")");
                break; //exit loop
            }
        }
    }
}

編集:このスクリプトを実行すると表示されるエラーは次のとおりです。

タイプ'System.ArgumentOutOfRangeException'の未処理の例外がmscorlib.dllで発生しました

追加情報:インデックスと長さは、文字列内の場所を参照する必要があります

私はAutoItの経験があります、それはC#での私の最初の日です^^よろしく

4

1 に答える 1

2

SOへようこそ。

配列の場合と同様に、ほとんどの座標やその他のものは0ベースです。

そうは言っても、ループにはBoundsのX / Y/WidthプロパティとHeightプロパティを使用するのが最適です。

var bounds = Screen.PrimaryScreen.Bounds;
for (int x = bounds.X; x < bounds.Width; x++) {
  for(int y = bounds.Y; y < bounds.Height; y++) {
    ..

また、ARGB値を16進数に変換する適切な方法は、string.Format()メソッドを使用することです。

string hex = string.Format("0x{0:8x}", argb);

編集:どうやらGraphics.CopyFromScreen明日がないようにハンドルをリークし、使用可能なハンドルがなくなると奇妙な例外がスローされるようになります(ソース

シナリオの簡単な回避策は、画面全体を1回キャプチャしてから、ビットマップで検索することです。Graphics.CopyFromScreen(new Position(0, 0), new Position(0, 0), new Size(bounds.Width, bounds.Height));

残念ながら、これは.Net 4.0では修正されませんでした(4.5についてはわかりません)。したがって、ここで説明するように、適切な解決策はネイティブGDI関数をP/Invokeすることだけのようです

于 2012-11-23T15:39:53.270 に答える