更快地读取文件并快速获取像素颜色?
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 等一些工具,因此像素的读取是单线程的,但您使用多线程来测试读取的值以查看它们是否正确。
我有以下代码并且它工作正常,但是,它工作得非常慢并且要读取带有记录的文件并分析每个像素 - 它花费的时间太长了。有什么办法可以让它工作得更快吗?
[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 等一些工具,因此像素的读取是单线程的,但您使用多线程来测试读取的值以查看它们是否正确。