2013-12-21 169 views
1

我試圖使用LockBits從位圖中讀取像素,但每次只需要2-4秒。爲什麼這種方法很慢?

這是方法:

public static Bitmap LockBits(Bitmap bmp) 
{ 
    PixelFormat pxf = PixelFormat.Format24bppRgb; 
    Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height); 
    BitmapData bmpData = 
    bmp.LockBits(rect, ImageLockMode.ReadWrite, pxf); 
    IntPtr ptr = bmpData.Scan0; 
    int numBytes = bmpData.Stride * bmp.Height; 
    byte[] rgbValues = new byte[numBytes]; 
    Marshal.Copy(ptr, rgbValues, 0, numBytes); 
    for (int counter = 0; counter < rgbValues.Length; counter += 6) 
     rgbValues[counter] = (byte)tolerancenumeric; 
    Marshal.Copy(rgbValues, 0, ptr, numBytes); 
    bmp.UnlockBits(bmpData); 
    bmp.Save(@"d:\testbmplockbits.bmp"); 
    return bmp; 
} 

此:(字節)tolerancenumeric爲值10之前,我改變它,這樣我可以改變從Form1中的NumericUpDown此值:

private void numericUpDown1_ValueChanged(object sender, EventArgs e) 
{ 
    CloudEnteringAlert.tolerancenum = (int)numericUpDown1.Value; 
    pictureBox1.Image = CloudEnteringAlert.LockBits(bitmapwithclouds); 
} 

我想用LockBits會使速度更快,但是當我點擊numericupdown來更改程序運行時的值時,它需要2-4秒,直到值更改並且圖片框中的圖像正在更新。

該方法有什麼問題?

+1

'bmp.Save(@ 「d:\ testbmplockbits.bmp」);'看起來像一個漂亮慢打給我。 –

+0

刪除保存現在我認爲它的速度稍快一點點,當點擊數字下拉時,延遲1-1.5秒。 – user3117033

+0

圖像有多大? – Dweeberly

回答

0

嘗試刷新你的圖片框:

pictureBox1.Refresh(); 
+0

我不認爲問題是刷新picturebox,無論如何,我沒有看到這個問題 – Fredou

+0

我跑上面的代碼對一個大圖像,它運行在毫秒,所以我只是猜測這個問題是圍繞無效/更新。 –

+0

尼克你是對的。我不敢說這是一個恥辱,但似乎我有另一個numericupdown事件textchanged事件,那裏我調用另一個方法,使用相同的位圖/秒,當我改變numericupdown值它被解僱這兩個事件。抱歉。 – user3117033

0

使用不安全的,這種運行快速

using System; 
using System.Drawing; 
using System.Drawing.Imaging; 
using System.Windows.Forms; 

namespace WindowsFormsApplication1 
{ 
public partial class Form1 : Form 
{ 
    Bitmap test = new Bitmap(512, 512, PixelFormat.Format24bppRgb); 

    public Form1() 
    { 
     InitializeComponent(); 
     numericUpDown1.Minimum = 0; numericUpDown1.Maximum = 255; 
    } 

    unsafe public static Bitmap LockBits(Bitmap bmp, int tolerancenumeric) 
    { 
     BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat); 

     byte* ptr = (byte*)bmpData.Scan0; 
     int numBytes = bmpData.Stride * bmp.Height; 

     for (int counter = 0; counter < numBytes; counter += 6) 
      *(ptr + counter) = (byte)tolerancenumeric; 

     bmp.UnlockBits(bmpData); 
     return bmp; 
    } 

    private void numericUpDown1_ValueChanged(object sender, EventArgs e) 
    { 
     pictureBox1.Image = LockBits(test, (int)numericUpDown1.Value); 
    } 
} 
} 
+2

您可能希望添加額外的詳細信息,說明爲什麼這會起作用(爲什麼內存分配和初始化會急劇減少)以及「令人擔憂的」;-)不安全的關鍵字/功能的潛在缺點。 – Dweeberly

+0

@Dweeberly,我認爲在google上有足夠的文檔可用,我所能做的就是警告他/她,你剛剛做了。我可以複製/粘貼一些鏈接,但是如果鏈接失效,建議不要這麼做:-) – Fredou

+0

只要您確切知道您在做什麼,在託管代碼中使用不安全上下文沒有任何問題。有時候,這是獲得可接受性能的唯一途徑。請記住,在使用指針之前,你應該把事情固定到位(GC可以是一個無情的b * itch哈哈) –