2013-12-21 4 views
1

Im пытается использовать 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 секунды, когда вы нажимаете numericupdown. – user3117033

+0

Насколько велика изображение? – Dweeberly

ответ

0

Попробуйте обновить на вашем PictureBox:

pictureBox1.Refresh(); 
+0

Я не думаю, что проблема заключается в обновлении picturebox, так или иначе я не видел эту проблему в вопросе – Fredou

+0

Я запустил код выше с большим изображением и работал в миллисекундах, поэтому я просто догадываюсь, что проблема вокруг invalidate/update. –

+0

Ник, ты был прав. Я боюсь сказать, что это позор, но кажется, что у меня есть другое событие события с переменным событием numericupdown, и там я вызывал другой метод, который использует один и тот же битмап/с, и когда я изменил значение 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 lol) –

Смежные вопросы