2014-05-05 405 views
0

好的,我創建了兩個程序。一個使用GetPixels,另一個使用LockBits。我的getPixels方案如下......BitLock-GetPixels。時間和PixelFormat

所指的條紋圖像爲200x200的JPG Referred to as stripe.jpg

Stopwatch GetTime = new Stopwatch(); 

Bitmap img = new Bitmap("stripe.jpg"); 
GetTime.Start(); 
for (int i = 0; i < img.Width; i++) 
{ 
    for (int j = 0; j < img.Height; j++) 
    { 
    Color pixel = img.GetPixel(i, j); 
    output += " " + pixel; 
    } 
} 
GetTime.Stop(); 

現在這一個讀出約20秒來處理此圖像輸出的所有像素。太棒了,但是我的LockBits理論上應該更快。我的LockBits的代碼是...

Bitmap bmp = new Bitmap("stripe.jpg"); 


Rectangle bmpRec = new Rectangle(0, 0, bmp.Width, bmp.Height); //Creates Rectangle for holding picture 

BitmapData bmpData = bmp.LockBits(bmpRec, ImageLockMode.ReadWrite, Pixels); //Gets the Bitmap data 

IntPtr Pointer = bmpData.Scan0; //Scans the first line of data 

int DataBytes = Math.Abs(bmpData.Stride) * bmp.Height; //Gets array size 

byte[] rgbValues = new byte[DataBytes]; //Creates array 

string Pix = " "; 

Marshal.Copy(Pointer, rgbValues, 0, DataBytes); //Copies of out memory 

bmp.UnlockBits(bmpData); 



Stopwatch Timer = new Stopwatch(); 

pictureBox1.Image = bmp; 

Timer.Start(); 
for (int p = 0; p < DataBytes; p++) 
{ 
    Pix += " " + rgbValues[p]; 
} 
Timer.Stop(); 

並且在那段時間是37secs。現在我不明白爲什麼我的時間比Lockbits長,而不是GetPixels。

此外,我的輸出文件不匹配它們在哪裏列出。這幾乎就像他們沒有秩序。

這是一個很大的問題需要解決,所以提前感謝大家閱讀並試圖解決我的問題。

+0

所有你在這裏計時的是字符串連接。我懷疑你的鎖定時間會更長,因爲你的圖像的寬度比寬度要長,而且你只是寫了更多的數據給字符串。要麼是這個,要麼是你正在測試的人爲因素。 – Blorgbeard

+0

而你的第一個代碼是以不同的順序寫入數據到第二個。首先是從上到下寫,然後從左到右 - 其次是從左到右,然後從上到下寫。 – Blorgbeard

回答

1

您可以看到幾個問題。最大的問題是,你的圖像寬度爲200,但在內存中,其stride是600(對我來說 - 可能類似於你)。這意味着你正在寫出更多的數據,因爲你不會忽略每行400個填充像素。

其他問題:

  1. 你只定時字符串連接。當你開始你的計時器時,lockbits的東西就完成了。
  2. 使用StringBuilder,您的字符串連接會更快。
  3. 當您只需要讀取時,您正在鎖定位圖以進行讀取/寫入訪問。用這張圖片對我來說沒有明顯的影響,但仍然可以將它改爲ReadOnly。
  4. 您的大部分意見都是不必要的(// creates array) - 有些誤導性(//Scans the first line of data - 不,它會返回指向已加載數據的指針)。

以下代碼僅在我的機器上的幾毫秒內完成。

Bitmap bmp = new Bitmap(@"d:\stripe.jpg"); 
//pictureBox1.Image = bmp; 

Stopwatch Timer = new Stopwatch(); 

Rectangle bmpRec = new Rectangle(0, 0, bmp.Width, bmp.Height); 
BitmapData bmpData = bmp.LockBits(
    bmpRec, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); 
IntPtr Pointer = bmpData.Scan0; 
int DataBytes = Math.Abs(bmpData.Stride) * bmp.Height; 
byte[] rgbValues = new byte[DataBytes]; 
Marshal.Copy(Pointer, rgbValues, 0, DataBytes); 
bmp.UnlockBits(bmpData); 

StringBuilder pix = new StringBuilder(" "); 
Timer.Start(); 
for (int i = 0; i < bmpData.Width; i++) 
{ 
    for (int j = 0; j < bmpData.Height; j++) 
    { 
     // compute the proper offset into the array for these co-ords 
     var pixel = rgbValues[i + j*Math.Abs(bmpData.Stride)]; 
     pix.Append(" "); 
     pix.Append(pixel); 
    } 
} 
Timer.Stop(); 

Console.WriteLine(Timer.Elapsed);