我在我的C#WinForms程序中檢查圖像的X列是否具有黑色像素。奇怪的「嘗試讀取或寫入受保護的內存」錯誤行爲
static Boolean GetColumnState(Bitmap bmp, int x, int col)
{
BitmapData pixelData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),ImageLockMode.ReadOnly,PixelFormat.Format32bppArgb);
Boolean state = false;
unsafe
{
int* pData = (int*)pixelData.Scan0.ToPointer();
pData += x;
for (int i = 0; i < bmp.Height; ++i)
{
pData += bmp.Width;
if (Color.FromArgb(*pData) == Color.FromArgb(255, col, col, col)) // error here
{ state = true; break; }
}
}
bmp.UnlockBits(pixelData);
return state;
}
可惜的是我得到
「試圖讀取或寫入保護內存」 在錯誤
「(Color.FromArgb(* pData所)== Color.FromArgb(255山口,山口,列))「線
下面是如何定義 」欄「,從不同的方法:
if (GetColumnState(b1, 0, 255) == false)
{ col = 255; }
else {col = 0;}
// more code + loops
GetColumnState(b1, i, col)
奇怪的是:我只有在像素顏色被定義爲255時纔會出錯。黑色)..
你如何解釋這一點?請注意,我正在編寫一個OCR程序,因此我使用不同的鍵值加載多個字典。我在OCR期間裁剪了很多圖片。 我的幸運猜測是線程互相混淆。
現在,我找到了解決這個問題的方法,但價格是+〜150-200ms到總腳本執行時間(這是不必要的價格,我認爲)。
通常我加載字典是這樣的:
Dictionary<string, Bitmap> lookup = new Dictionary<string, Bitmap>();
Bitmap l0 = new Bitmap(@"C:\xxx\0.bmp", true);
//+15 more
lookup.Add("0", l0);
//+15 more
Dictionary<string, Bitmap> lookup2 = new Dictionary<string, Bitmap>();
Bitmap nAa = new Bitmap(@"C:\yyy\Aa.bmp", true);
//+15 more
lookup2.Add("A", nAa);
//+15 more
要解決這個問題,我要創建「空洞」爲每個字典並加載它們在不同的線程,就像這樣:
void loadNumbers1()
{
lookup4 = new Dictionary<string, Bitmap>();
Bitmap sd = new Bitmap(@"C:\xxxxx\a.bmp", true);
//+15 more
lookup4.Add("0", s0);
//+15 more
}
void loadNumbers2()// 4, 5, 6,
{
//repeat
}
現在我們推出線程:
Thread tNum2= new Thread(new ThreadStart(loadNumbers2));
tNum2.Start();
Thread tNum3= new Thread(new ThreadStart(loadNumbers3));
tNum3.Start();
最後一步(沒有t他一步程序運行速度更快,但是會出現誤差往往):
tNum3.Join();
就是這樣,現在我沒有任何問題,但執行時間較長..如何在一個解決這個問題的任何想法更簡單的方法,而不使用多個線程?在我的情況下,沒有連接()我得到5-100ms字典加載時間,加入() - 高達300毫秒。沒有線程 - 最多180(如果錯誤沒有發生)。
對不起長期後
編輯:(永久性的修復)
static unsafe Boolean GetColumnState(Bitmap bmp, int x, int col)
{
BitmapData pixelData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),ImageLockMode.ReadOnly,PixelFormat.Format32bppArgb);
Boolean state = false;
unsafe
{
byte[] buffer = new byte[pixelData.Height * pixelData.Stride];
Marshal.Copy(pixelData.Scan0, buffer, 0, buffer.Length);
for (int i = 0; i < pixelData.Height - 1; ++i)
{
byte red = buffer[i * pixelData.Stride + 4 * x + 2];
if (red == col)
{ state = true; break; }
}
}
bmp.UnlockBits(pixelData);
return state;
}
我不明白什麼是錯關於指針,而是一個字節工作的偉大。 @tia感謝您指出我的問題。
有誰知道爲什麼多線程減慢字典加載時間而不是加速它?
好的,我不得不徹底刪除指針,因爲我根本不理解它們,而是使用Byte []代替。請參閱編輯。無論如何,線程爲什麼會減慢執行時間這麼多? – Alex 2012-03-24 16:30:31