Отображать окно изображения быстрее - PullRequest
7 голосов
/ 25 августа 2010

Я пытаюсь быстро загрузить изображения в коробку с картинками и нарисовать их. У меня задержка в 0,13 секунды между моментом, когда я назначаю растровое изображение графическому блоку, и когда он появляется. И всякий раз, когда я делаю picturebox.refresh(), перед вызовом метода рисования будет та же самая задержка в .13 - .15 секунд. Есть ли способ избавиться от этой задержки?

Я использую C # в Visual Studio 2010. Я загружаю изображения с помощью библиотеки FreeImage.

Вот код в моем событии pictureBox_MouseMove:

if (IsMouseDown || DrawLine.Checked || IsMovingBox)  
{  
  Tracing.Trace("Update Picture Box");  
  pictureBox.Refresh();  
} 

Затем я прослеживаю линию, когда вызывается мое событие рисования. Задержка между двумя линиями трассировки.

Если я использую битовое изображение в формате 117 КБ, задержка составит .13 секунд. Для загрузки этого изображения в память требуется 0,04 секунды. Для замены моего растрового изображения в этом окне требуется 0,01 секунды.

Если я использую jpg-изображение в оттенках серого на 1125 КБ, задержка составляет 0,14 секунды. Для загрузки этого изображения в память требуется .26 секунд. Для замены моего растрового изображения в этом окне требуется 0,03 секунды.

1 Ответ

12 голосов
/ 25 августа 2010

Если в вашем коде нет других задержек, которые бы препятствовали повторному входу потока пользовательского интерфейса в цикл сообщений, так что можно вызвать метод OnPaint (): ваш обработчик событий Paint вызывается после PictureBoxнарисовал изображение.Это еще не видно, PB использует двойную буферизацию.

Это изображение становится дорогим для рисования, когда его нужно изменить в соответствии с клиентской областью PB.Что очень вероятно в вашем случае, потому что ваши изображения довольно большие.Он использует высококачественный бикубический фильтр, чтобы изображение с измененным размером выглядело хорошо.Это довольно дорого, хотя результат и хороший.

Чтобы избежать этих затрат, измените размер изображения самостоятельно, прежде чем присваивать его свойству Image.Сделайте его таким же большим, как ClientSize PB.

Это само по себе будет иметь большое значение.Следующее, что вы можете сделать, это создать масштабированное растровое изображение с пиксельным форматом 32bppPArgb.Этот формат примерно в 10 раз быстрее, чем любой другой, потому что он соответствует видеоадаптеру на большинстве компьютеров, поэтому преобразование формата пикселей не требуется.

Некоторый код:

    private void loadImage(string path) {
        using (var srce = new Bitmap(path)) {
            var dest = new Bitmap(pictureBox1.Width, pictureBox1.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
            using (var gr = Graphics.FromImage(dest)) {
                gr.DrawImage(srce, new Rectangle(Point.Empty, dest.Size));
            }
            if (pictureBox1.Image != null) pictureBox1.Dispose();
            pictureBox1.Image = dest;
        }
    }

Вы, вероятно,хочу повозиться с этим, чтобы изображение сохранило свое соотношение сторон.Попробуйте сначала как есть, чтобы убедиться, что вы получите улучшение перф.

...