C# 位锁获取像素。时间和像素格式

C# 位锁获取像素。时间和像素格式,c#,graphics,pixels,getpixel,lockbits,C#,Graphics,Pixels,Getpixel,Lockbits,好的,我创建了两个程序。一个使用GetPixels,另一个使用LockBits。我的GetPixels程序如下所示 参考的条纹图片是200x200 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;

好的,我创建了两个程序。一个使用
GetPixels
,另一个使用
LockBits
。我的GetPixels程序如下所示

参考的条纹图片是200x200 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();
Stopwatch GetTime=new Stopwatch();
位图img=新位图(“stripe.jpg”);
GetTime.Start();
对于(int i=0;i
现在这一个读出大约20秒来处理这个图像并输出所有像素。很好,但我的锁具理论上应该更快。我的密码是

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();
Bitmap bmp=新位图(“stripe.jpg”);
矩形bmpRec=新矩形(0,0,bmp.Width,bmp.Height)//创建用于保存图片的矩形
BitmapData bmpData=bmp.LockBits(bmpRec,ImageLockMode.ReadWrite,像素)//获取位图数据
IntPtr Pointer=bmpData.Scan0//扫描第一行数据
int DataBytes=Math.Abs(bmpData.Stride)*bmp.Height//获取数组大小
字节[]rgbValues=新字节[数据字节]//创建数组
字符串Pix=“”;
副本(指针,RGB值,0,数据字节)//内存不足的副本
bmp.UnlockBits(bmpData);
秒表计时器=新秒表();
pictureBox1.Image=bmp;
Timer.Start();
for(int p=0;p
时间是37秒。现在我不明白为什么我花在锁位上的时间比花在获取像素上的时间要长

此外,我的输出文件在列出的位置上也不匹配。这几乎就好像它们出了故障


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

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

其他问题:

  • 您只对字符串连接进行计时。当你启动计时器时,锁位的工作已经完成了
  • 使用StringBuilder,字符串连接会更快
  • 当您只需要读取时,您正在锁定位图以进行读/写访问。这张图片对我的性能没有明显的影响,但还是把它改为只读吧
  • 您的大多数注释充其量都是不必要的(
    //创建数组
    )-有些注释具有误导性(
    //扫描第一行数据
    -否,它返回指向已加载数据的指针)
  • 在我的机器上,以下代码仅在几毫秒内完成

    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);
    
    Bitmap bmp=新位图(@“d:\stripe.jpg”);
    //pictureBox1.Image=bmp;
    秒表计时器=新秒表();
    矩形bmpRec=新矩形(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;
    字节[]rgbValues=新字节[数据字节];
    副本(指针,RGB值,0,数据字节);
    bmp.UnlockBits(bmpData);
    StringBuilder pix=新的StringBuilder(“”);
    Timer.Start();
    对于(int i=0;i
    这里的所有计时都是字符串连接。我怀疑使用锁定位的时间会更长,因为图像的跨步比其宽度长,而且您只是在向字符串写入更多数据。要么是这样,要么就是测试方式的产物。第一个代码以不同的顺序将数据写入第二个代码。第一种是从上到下再从左到右写,第二种是从左到右再从上到下写。