BitLock技术-的getPixels。时间和PixelFormat

时间:2014-05-05 03:30:35

标签: c# graphics pixels getpixel lockbits

好的,我已经创建了两个程序。一个使用GetPixels,另一个使用LockBits。我的GetPixels计划如下......

引用的条纹图片是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();

,时间就是37秒。现在我不明白为什么Lockbits的时间比GetPixels的时间长。

此外,我的输出文件在列出的位置方面也不匹配。这几乎就好像它们已经失灵了。

这是一个需要解决的大问题,所以提前感谢大家阅读并试图解决我的问题。

1 个答案:

答案 0 :(得分:1)

我可以看到一些问题。最大的问题是你的图像宽度为200,但在内存中,它的stride是600(对我来说 - 可能与你相似)。这意味着您要写出更多数据,因为您不会忽略每行400个填充像素。

其他问题:

  1. 您只是计时字符串连接。当你启动你的计时器时,lockbits的东西已经完成了。
  2. 使用StringBuilder,您的字符串连接会更快。
  3. 当您只需要阅读时,您将锁定位图以进行读/写访问。对于我来说,使用此图像对性能没有明显影响,但仍然可以将其更改为ReadOnly。
  4. 你的大部分评论都是不必要的(// creates array) - 有些是误导性的(//Scans the first line of data - 不,它会返回一个指向已加载数据的指针。)
  5. 以下代码在我的计算机上仅在几毫秒内完成。

    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);