更快地读取文件并快速获取像素颜色?

Read the file faster and get the pixel color quickly?

我有以下代码并且它工作正常,但是,它工作得非常慢并且要读取带有记录的文件并分析每个像素 - 它花费的时间太长了。有什么办法可以让它工作得更快吗?

[DllImport("user32.dll")]
static extern IntPtr GetDC(IntPtr hwnd);
[DllImport("user32.dll")]
static extern Int32 ReleaseDC(IntPtr hwnd, IntPtr hdc);
[DllImport("gdi32.dll")]
static extern uint GetPixel(IntPtr hdc, int nXPos, int nYPos);

static void Main(string[] args)
{
    if (isCorrect("test.LOB"))
    {
        Console.WriteLine("Yes");
    }
    else
    {
        Console.WriteLine("Nope...");
    }
    Console.ReadKey();
    //Record("test", 0, 0, 50, 50, 10);
}

public static void Record(string name, int start_x, int start_y, int end_x, int end_y, int max_Difference)
{
    string path = name + ".LOB";
    string result;
    Color pixel_Result;
    for (int x = start_x; x <= end_x; x++)
    {
        for (int y = start_y; y <= end_y; y++)
        {
            pixel_Result = GetPixelColor(x, y);
            result = x + "|" + y + "|" + pixel_Result.R + "|" + pixel_Result.G + "|" + pixel_Result.B + "|" + max_Difference;
            if (!File.Exists(path))
            {
                using (StreamWriter sw = File.CreateText(path))
                {
                    sw.WriteLine(result);
                }
            }
            else
            {
                using (StreamWriter sw = File.AppendText(path))
                {
                    sw.WriteLine(result);
                }
            }
        }
    }
}

public static bool isCorrect(string path)
{
    using (StreamReader sr = File.OpenText(path))
    {
        string result = "";
        string[] correctedResult;
        while ((result = sr.ReadLine()) != null)
        {
            correctedResult = result.Split('|');
            int X = Convert.ToInt32(correctedResult[0]);
            int Y = Convert.ToInt32(correctedResult[1]);
            int R = Convert.ToInt32(correctedResult[2]);
            int G = Convert.ToInt32(correctedResult[3]);
            int B = Convert.ToInt32(correctedResult[4]);
            int maxDifference = Convert.ToInt32(correctedResult[5]);
            Color c;
            c = GetPixelColor(X, Y);
            maxDifference /= 2;
            if (R < c.R - maxDifference || R > c.R + maxDifference)
            {
                return false;
            }
            if (G < c.G - maxDifference || G > c.G + maxDifference)
            {
                return false;
            }
            if (B < c.B - maxDifference || B > c.B + maxDifference)
            {
                return false;
            }
        }
        return true;
    }
}

static public Color GetPixelColor(int x, int y)
{
    IntPtr hdc = GetDC(IntPtr.Zero);
    uint pixel = GetPixel(hdc, x, y);
    ReleaseDC(IntPtr.Zero, hdc);
    Color color = Color.FromArgb((int)(pixel & 0x000000FF),
                 (int)(pixel & 0x0000FF00) >> 8,
                 (int)(pixel & 0x00FF0000) >> 16);
    return color;
}

提前致谢!

有两个主要问题会降低您的代码速度。首先,你打开和关闭流写入器的每个像素,这会非常慢。将开口移到环路之外。还有一个 StreamWriter 的构造函数,可以让你指定追加模式,这样你就不需要你的 if/else 检查。

第二个问题是你也在每个像素打开和关闭你的 IntPtr 句柄,这会很慢,打开一次然后在完成后关闭它。

static public Color GetPixelColor(int x, int y, IntPtr hdc)
{
    uint pixel = GetPixel(hdc, x, y);
    Color color = Color.FromArgb((int)(pixel & 0x000000FF),
                 (int)(pixel & 0x0000FF00) >> 8,
                 (int)(pixel & 0x00FF0000) >> 16);
    return color;
}

public static bool isCorrect(string path)
{
    IntPtr hdc = GetDC(IntPtr.Zero);
    try
    {
        using (StreamReader sr = File.OpenText(path))
        {
            string result = "";
            string[] correctedResult;
            while ((result = sr.ReadLine()) != null)
            {
                correctedResult = result.Split('|');
                int X = Convert.ToInt32(correctedResult[0]);
                int Y = Convert.ToInt32(correctedResult[1]);
                int R = Convert.ToInt32(correctedResult[2]);
                int G = Convert.ToInt32(correctedResult[3]);
                int B = Convert.ToInt32(correctedResult[4]);
                int maxDifference = Convert.ToInt32(correctedResult[5]);
                Color c;
                c = GetPixelColor(X, Y, hdc);
                maxDifference /= 2;
                if (R < c.R - maxDifference || R > c.R + maxDifference)
                {
                    return false;
                }
                if (G < c.G - maxDifference || G > c.G + maxDifference)
                {
                    return false;
                }
                if (B < c.B - maxDifference || B > c.B + maxDifference)
                {
                    return false;
                }
            }
            return true;
        }
    }
    finally
    {
        ReleaseDC(IntPtr.Zero, hdc);
    }
}

public static void Record(string name, int start_x, int start_y, int end_x, int end_y, int max_Difference)
{
    string path = name + ".LOB";

    string result;
    Color pixel_Result;

    IntPtr hdc = GetDC(IntPtr.Zero);
    try
    {
        using (StreamWriter sw = new StreamWriter(path, append:true))
        {
            for (int x = start_x; x <= end_x; x++)
            {
                for (int y = start_y; y <= end_y; y++)
                {
                    pixel_Result = GetPixelColor(x, y, hdc);
                    result = x + "|" + y + "|" + pixel_Result.R + "|" + pixel_Result.G + "|" + pixel_Result.B + "|" + max_Difference;
                    sw.WriteLine(result);
                }
            }
        }
    finally
    {
        ReleaseDC(IntPtr.Zero, hdc);
    }
}

如果在修复 GetPixelColor 中的缓慢问题后代码仍然太慢,我会推荐 运行 对代码进行分析器以查看缓慢来自哪一部分,您可以使用流水线工作TPL DataFlow 等一些工具,因此像素的读取是单线程的,但您使用多线程来测试读取的值以查看它们是否正确。