![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
В реальном времени нужно рисовать график(и) данных. [D6]
SergeyG © (2007-05-24 12:46:00)Пакеты данных приходят каждые 50 мс (через СОМ-порт). После некоторой обработки на Image1 (расположенной на Form1) нужно поставить точку, соответстующую значению параметра. Размер Image - 500х320. График рисуется так: сначала он "ползет" в правой половине, доходит до конца, изображение правой половины переносится в левую половину, и снова ползет в правой половине. Для рисования использую Bitmap, который заполняется с помощью ScanLine[y], а вывод на Image - Image1.Picture.Graphic:=Bitmap. Ну, еще вывод делаю после прихода четырех пакетов.
Все хорошо, но проблема в том, что при выводе на Image дергается фон изображения.
Как это победить?
Приведу кусочек кода формирования изображения:
//ввод в Битмап черной точки, соотв. параметру Ang2
p:=Bitmap.ScanLine[(Bh div 2)-(Ang2 div 4)];
p[(CntRun+Cnt4)*3]:=0;
p[(CntRun+Cnt4)*3+1]:=0;
p[(CntRun+Cnt4)*3+2]:=0;
inc(Cnt4);
if Cnt4=4 then
//ввели 4 столбика в Битмап - выводим на экран
begin
Cnt4:=0;
Image1.Picture.Graphic:=Bitmap;
inc(CntRun,4);
if CntRun>=Bw then
//закончились полэкрана
begin
CntRun:=Bw div 2;
for h1:=0 to (Bh-1) do
begin
p:=Bitmap.ScanLine[h1];
for w:=0 to ((Bw div 2)-1) do
begin
//перезапись второго полэкрана в первый
//и очистка второго полэкрана
R1:=p[(w+(Bw div 2))*3];
p[(w+(Bw div 2))*3]:=$A0; //цвет фона
G:=p[(w+(Bw div 2))*3+1];
p[(w+(Bw div 2))*3+1]:=$A0;; //цвет фона
B:=p[(w+(Bw div 2))*3+2];
p[(w+(Bw div 2))*3+2]:=$A0;; //цвет фона
p[w*3]:=R1;
p[w*3+1]:=G;
p[w*3+2]:=B;
end;
end;
end;
end;
Application.ProcessMessages
Bh и Bw - высота и ширина Битмапа и Имиджа,
CntRun - счетчик полэкрана,
Cnt4 - счетчик 4 столбиков.
Где-то раньше:
procedure TForm1.FormCreate(Sender: TObject);
begin
Bitmap:=TBitmap.create;
Bitmap.PixelFormat:=pf24bit;
Bitmap.Height:=Bh;
Bitmap.Width:=Bw;
end;
Darvin (2007-05-24 15:25:00) [1]Все должно успевать за 50 мс. У меня подобная проблема, но 20 мс и все успевает и даже проц не грузит. Я рисую не на битмапе, а на канве TPaintBox, что вообщем-то неважно.
НО! В каждый момент времени (дискретно 20 / 50 мс) нужно рисовать не весь битмап, а только измененную часть. Тогда никаких тормозов не будет.
Лучше это сделать в своем компоненте - наследнике, например того-же TPaintBox. В нем нужно организовать метод GetData (CurValue), в котором:
а) Рисовать отсчет
б) Запоминать его во внутреннем буфере.
Также в компоненте стоит переопределить метод Paint, в котором выполнять перерисовку всех данных из внутреннего буфера. Метод Paint будет вызываться тогда, когда компоненту будут приходить события WM_PAINT, например при сворачивании окна, перекрывающего твой компонент, намного реже, чем 20 мс.
MBo (2007-05-24 15:21:00) [2]>Вот только дергание фона Имиджа
может помочь установка DobleBuffered для родителя TImage (формы, видимо)
Kolan (2007-05-24 15:13:00) [3]> тоже использовал TChart
TFastLine? Кроме того есть на сайте раздел форума(кажется) RealTimeCharting
SergeyG (2007-05-24 14:59:00) [4]на ABN:
я как раз и рисую в памяти (в Bitmap). А захлебывания вроде нет, т.к. график ползет равномерно, без рывков. Вот только дергание фона Имиджа.
на Jeer:
но это же рисование с помощью MoveTo, LineTo ?. Но у меня может быть рисование до десятка параметров. Может тоже не успеть. Да еще с учетом сетки.
Jeer (2007-05-24 14:45:00) [5]Очистить точку по старым координатам
Нарисовать по новым
и все
ANB (2007-05-24 14:40:00) [6]Однако все равно рисование можеть "захлебнуться", посему лучше разнести процесс чтения данных и собственно рисование графика, продумав вопрос - чего делать, если пришедшие данные таки не успевают отображаться.
ANB (2007-05-24 14:38:00) [7]
> SergeyG © (24.05.07 12:46)
Буферизацию надо включить. Или самому ее организовать - т.е. рисовать кусок изображения в памяти и за раз (BitBlt вроде как) выводить на экран.
SergeyG (2007-05-24 14:07:00) [8]50 мс это не так мало, поэтому рисовать надо все.
Вам бы быть моим начальником, который говорил бы, что делать ничего не надо :-).
Германн (2007-05-24 13:53:00) [9]
> В реальном времени нужно рисовать график(и) данных.
В "реальном времени" нужно только принимать данные с целью их последующего сохранения, например в файл. А рисовать их всевовсе не обязательно.
SergeyG (2007-05-24 13:47:00) [10]нам один программер пытался помочь, тоже использовал TChart, но захлебнулся (и тот и другой :)). Не успевает отработать за около 50 мс.
S@shka (2007-05-24 13:09:00) [11]Не в тему но почему ж для графиков не юзать мощный TChart? ))