2014-05-05 207 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);