Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме 15-35 тыс рублей в месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 25.11.2020, 15:45   #1
Armageddets
Форумчанин
 
Регистрация: 30.06.2012
Сообщений: 145
По умолчанию Самый быстрый способ прорисовки на компоненте Image

Здравствуйте. Подскажите каким методом можно максимально уменьшить нагрузку на компьютер при прорисовке изображений на компоненте Image 1?

Я пробовал рисовать через Canvas.Draw - но если нужно рисовать много изображений и хорошей частотой кадров - начинаются лаги (даже если ограничить прорисовку только видимой частью изображения)

Так же пробовал рисовать через bitblt, но нагрузка тоже сильно не уменьшилась.

Пробовал через движок Andorra2d, но там, если я правильно понял - прорисовка идет только в само окно формы, на компонентах рисовать нельзя (по крайней мере такой информации я не нашел).

Можно ли средствами DirectX, OpenGL или еще какими-то сделать прорисовку изображений максимально быстрой на одном из визуальных компонентах (Image, PaintBox и т.д.)? И есть ли существенная разница в скорости прорисовки Bmp и Jpeg с учетом разницы размера файлов одинакового разрешения? Рисую на канве через компонент Timer.

Заранее спасибо за советы.
Armageddets вне форума Ответить с цитированием
Старый 25.11.2020, 16:47   #2
Arigato
Высокая репутация
СуперМодератор
 
Аватар для Arigato
 
Регистрация: 27.07.2008
Сообщений: 16,014
По умолчанию

Через SetDIBitsToDevice. Набросал пример, на форме PaintBox1 и кнопка:
Код:
const
  W = 500; // ширина PaintBox
  H = 500; // высота PaintBox

var
  // массив пикселей (можно диначический, но там чуть сложнее)
  Bits: array[0..H-1,0..W-1] of TColor;
  BitsInfo: BITMAPINFO;

// отрисовка массива на устройство DC:
function DrawToDC(DC: HDC; X, Y, Width, Height: Integer): Integer;
begin
  with BitsInfo.bmiHeader do
  begin
    biWidth := Width;
    biHeight := -Height;
  end;
  Result := SetDIBitsToDevice(
    DC,
    X, Y, Width, Height,
    0, 0, 0, Height,
    @Bits, BitsInfo, DIB_RGB_Colors
  );
end;

// рисуем точку
procedure Plot(x,y: Integer; C: TColor);
begin
  if (x>=0) and (y>=0) and (x<W) and (y<H) then begin
    Bits[y,x] := C;
  end;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
var
  i,t: Integer;
begin
  Randomize;
  t:=GetTickCount;
  // очищаем поле для рисования
  FillChar (Bits, W*H*4, 0);
  // рисуем миллион точек!
  for i := 1 to 1000000 do begin
    Plot(Random(W), Random(H), RGB(Random(256),Random(256),Random(256)));
  end;
  DrawToDC(PaintBox1.Canvas.Handle, 0, 0, W, H);
  ShowMessage(IntToStr(GetTickCount-t)+' мс');
end;

initialization

with BitsInfo, bmiHeader do
begin
  biSize := SizeOf (bmiHeader);
  biWidth := 0;
  biHeight := 0;
  biPlanes := 1;
  biBitCount := 32;
  biCompression := BI_RGB;
  biSizeImage := 0;
  biXPelsPerMeter := 0;
  biYPelsPerMeter := 0;
  biClrUsed := 0;
  biClrImportant := 0;
end;
Миллион точек рисует менее чем за 16 мс.

Последний раз редактировалось Arigato; 25.11.2020 в 16:51.
Arigato вне форума Ответить с цитированием
Старый 25.11.2020, 18:19   #3
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Советую вопрос задать на FreePascal.ru
У нас там была тема про отрисовки линий с бенчмаркинг.

Цитата:
Так же пробовал рисовать через bitblt, но нагрузка тоже сильно не уменьшилась.
Чем меряете нагрузку и как?

Какой режим отрисовки установлен у формы? С буфферизацией али без? С двойной или тройной?
Изображения в системной памяти или закэшированы в видеопамяти?

Цитата:
Можно ли средствами DirectX, OpenGL или еще какими-то сделать прорисовку изображений максимально быстрой на одном из визуальных компонентах (Image, PaintBox и т.д.)?
Да. Там свои компоненты. Если рисовать на плоскости экрана в полнооконном режиме, то обычно работать ещё быстрее.

Цитата:
И есть ли существенная разница в скорости прорисовки Bmp и Jpeg
Логично что jpeg надо декодировать, а потом рисовать.

Цитата:
Я пробовал рисовать через Canvas.Draw - но если нужно рисовать много изображений и хорошей частотой кадров - начинаются лаги (даже если ограничить прорисовку только видимой частью изображения)
Какие лаги? Уверены, что это не лаги таймера?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 26.11.2020, 00:41   #4
Armageddets
Форумчанин
 
Регистрация: 30.06.2012
Сообщений: 145
По умолчанию

Нагрузку в своем примере не измерял конкретную, но кулер начинает крутится гораздо быстрее, перетягивание окна подлагивает и некоторые действия с мышкой тоже. Интервал в таймере стоит 50. Картинки размера 256х256 bmp 24 Бита. Прорисовка картинок в несколько слоев (картинки текстур, а поверх картинки с прозрачностью) на графический буфер (динамически созданная TBitmap). Картинки загружены в массив картинок TBitmap; На форме буферизацию не выставлял.

Спасибо за советы. Верхний пример работает очень быстро. Теперь попробую его адаптировать под прорисовку не пикселей, а картинок bmp.
Armageddets вне форума Ответить с цитированием
Старый 26.11.2020, 00:47   #5
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Цитата:
Сообщение от Armageddets Посмотреть сообщение
и некоторые действия с мышкой тоже.
Это вообще похоже на то что уперлись в производительность жёсткого диска.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 26.11.2020, 01:28   #6
Armageddets
Форумчанин
 
Регистрация: 30.06.2012
Сообщений: 145
По умолчанию

Возможно, хотя стоит SSD диск. Но он неизвестной китайской фирмы - поэтому - все может быть. Ну или же я где-то неправильно что-то сделал - это тоже не исключено.
Armageddets вне форума Ответить с цитированием
Ответ
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Самый быстрый способ получить размер файла xexxex Win Api 12 17.04.2015 01:42
android самый быстрый способ запустить приложение Deight Мобильные ОС (Android, iOS, Windows Phone) 2 13.10.2013 12:53
Самый быстрый способ задать цвет пикселю Terrance! Общие вопросы Delphi 13 05.12.2011 12:40
Ищу самый быстрый способ работы с файлами trunc Общие вопросы Delphi 6 15.10.2011 12:21
Самый быстрый способ проверить прокси? TwiX Работа с сетью в Delphi 6 15.02.2010 22:41