Russian Qt Forum
Ноябрь 23, 2024, 05:46 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: прорисовка не успевает  (Прочитано 9500 раз)
Firefox
Гость
« : Декабрь 06, 2011, 17:51 »

доброго времени суток всем. у меня такая вот проблемка: рисую круговую развертку, но прорисовка не поспевает за таймером. то есть - есть картинка 800х800 пикселов.  от центра каждый 0,667 сек должен рисоваться круг радиусом R, причем радиус каждый цикл возрастает. но окружность внутри заполняется точками(drawPoint), так как точка каждая имеет свой цвет. воти получается, что при нарастании круга уже с 5-6 цикла никак обновление и прорисовка не укладываются в 0.667 сек, а под конец вообще доходит до 8-10 сек, что неприемлемо совершенно. рисую обыкновенно через QPainter в QImage потом отображаю. Может есть способы более быстрой прорисовки.  Буду рада идеям.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #1 : Декабрь 06, 2011, 18:01 »

Какая платформа? Какой формат QImage? Включено ли сглаживание?
Записан

Qt 5.11/4.8.7 (X11/Win)
BRE
Гость
« Ответ #2 : Декабрь 06, 2011, 18:02 »

но окружность внутри заполняется точками(drawPoint)
Вот так не надо заполнять, нужно работать напрямую с буфером QImage.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Декабрь 06, 2011, 18:24 »

Конечно если рисование не укладывается по времени - в первую очередь надо подумать как ee ускорить (о чем уже сказали выше).

Но так или иначе неизбежны ситуации когда нужно прервать отрисовку когда она уже не имеет смысла. Простой пример - пользователь тянет мышу. Если тянет "достаточно  медленно" - все хорошо, все 100K точек успели отрисоваться. Но если с бодуна или человек нервный - не успели. Нормальный софт должен это отрабатывать и выскакивать из paint если он уже потерял актуальность. Напр проверяя текущую позицию мыши через каждые N точек. Такого рода "маленькие тонкости" и есть отличия профессионального софта от "философии гну"  Улыбающийся
Записан
Firefox
Гость
« Ответ #4 : Декабрь 06, 2011, 22:04 »

Вот так не надо заполнять, нужно работать напрямую с буфером QImage.
а это не так разве??как тогда напрямую в QImage?
Код:
int Radiuse=20;
QImage *img;
img = new QImage(frame1);
frame1->installEventFilter(this);

QTimer *tm;
tm=new QTimer(this);
connect(tm,SIGNAL(timeout()),SLOT(DRAWW()));
tm->start(667);
...
eventFilter()
{
 ...
if(obj==frame1)
{
Qpainter pnt;
pnt->drawImage(0,0,*img,0,0,0);
}
}

void Draw_shum()
{
QPainter pnt2(img);
radiuse+=20;
if(radiuse>380)tm->stop();
// x, y - координаты точек в массиве
if(radiuse>=sqrt(x*x+y*y))
{
     pnt.setPen(QColor("из массива случайных чисел берется"));
     pnt.drawPoint(x,y);
}
}

void DRAWW()
{
Draw_shum();
frame1->update();
}

организация примерно такая. платформа VS2003 qt 4.4.3
« Последнее редактирование: Декабрь 06, 2011, 22:18 от Firefox » Записан
BRE
Гость
« Ответ #5 : Декабрь 06, 2011, 22:05 »

Я про то, как заполняется этот QImage. Не нужно использовать drawPoint - это очень медленно.

Записан
Firefox
Гость
« Ответ #6 : Декабрь 06, 2011, 22:19 »

поясните на пальцах тогда как???функциями. я вроде рисуу на имежде но в паинтер.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #7 : Декабрь 06, 2011, 22:21 »

Заполнять QImage нужно минимум через QImage::setPixel().

Код
C++ (Qt)
eventFilter()
{
     ...
     if(obj==frame1)
     {
           Qpainter pnt;
           pnt->drawImage(0,0,*img,0,0,0);
     }
}
При каких именно событиях делается pnt->drawImage()?
И почему нельзя было отнаследоваться от QFrame и не перегрузить QFrame::paintEvent() и уже в нём делать отрисовку.
eventFilter() как-то несеръёзно для этого использовать.
« Последнее редактирование: Декабрь 06, 2011, 22:25 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
Firefox
Гость
« Ответ #8 : Декабрь 06, 2011, 22:24 »

а это разве реально быстрее???
Записан
Firefox
Гость
« Ответ #9 : Декабрь 06, 2011, 22:32 »

спасибо завтра обязательно попробую. просто сталкиваюсь с прорисовкой графики впервые и как в коллективе посоветовали(через eventFilter у нас работают многие) так и реализовала.
Записан
Firefox
Гость
« Ответ #10 : Декабрь 07, 2011, 10:54 »

Что-то у меня не отображается. Подскажите ошибку. Сделала вот как
Код:
// конструктор
img_obp1 = new QImage( frame_obp->width(), frame_obp->height(), QImage::Format_RGB32);
void pr::paintEvent(QPaintEvent *pe)
{
frame_obp->paintEvent(pe); // РУГАЕТСЯ НА ЭТУ СТРОЧКУ  error C2248: 'QFrame::paintEvent' : cannot access protected member declared in class 'QFrame'
// если убрать верхнюю строчку не рисуется ничего
QPainter p(frame_obp);
p.drawImage(0,0,*img_obp1,0,0,0,0);

}
//слот таймера 0.6 сек
// старт таймера по кнопке происходит
void pr::Krug()
{
Draw_shum();
frame_obp->update();
}
// функция прорисовки
void pr::Draw_shum()
{
QRgb rgb_col;
int col=0,r_col=0,g_col=0,b_col=0,rez=0;
acc_d->Detection_account();

// расчет радиуса прорисовки на 1 цикл
if(D_shkala>0)
Radius+=4*48/D_shkala;
if(Radius>=384 && T_obmen->isActive()==true)
{
KRUG_DRAW_SHUM->stop();
return;
}

float Rez1=0;
int count_r=0, count_g=0;
QString str;
int Num_col=0;
int i,j;
for (i=0;i<384;i++)
{
for(j=0;j<384;j++)
{

Rez1=sqrt((float)((i)*(i)+(j)*(j)));
if(Radius>Rez1 )//условие попадет ли точка в сектор окружности радиуса Radius
{
// верхний правый сектор отображается
Num_col=acc_d->OUT_STR.Rastr[i+384][384-j];
if(Num_col>=255) r_col=255;
if(Num_col<=0)r_col=0;
if(Num_col>0 && Num_col<255)r_col=byr_colors[Num_col][0];
if(Num_col>=255)g_col=255;
if(Num_col<=0)g_col=0;
if(Num_col>0 && Num_col<255)g_col=byr_colors[Num_col][1];
if(Num_col>=255)b_col=255;
if(Num_col<=0)b_col=0;
if(Num_col>0 && Num_col<255)b_col=byr_colors[Num_col][2];
img_obp1->setPixel(i,-j,qRgb(r_col,g_col,b_col));
// проверка
if(r_col>0)
count_r++;
LE_1->setText(str.setNum(count_r));
if(g_col>0)
count_g++;
LE_2->setText(str.setNum(count_g));
//

// нижний правый сектор окружности отображается
Num_col=acc_d->OUT_STR.Rastr[i+384][384+j];
if(Num_col>=255)r_col=255;
if(Num_col<=0)r_col=0;
if(Num_col>0 && Num_col<255)r_col=byr_colors[Num_col][0];
if(Num_col>=255)g_col=255;
if(Num_col<=0)g_col=0;
if(Num_col>0 && Num_col<255)g_col=byr_colors[Num_col][1];
if(Num_col>=255)b_col=255;
if(Num_col<=0)b_col=0;
if(Num_col>0 && Num_col<255)b_col=byr_colors[Num_col][2];
img_obp1->setPixel(i,j,qRgb(r_col,g_col,b_col));

// проверка
if(r_col>0)
count_r++;
LE_1->setText(str.setNum(count_r));
if(g_col>0)
count_g++;
LE_2->setText(str.setNum(count_g));
//


// нижний левый сектор окружности отображается
Num_col=acc_d->OUT_STR.Rastr[384-i][384-j];
if(Num_col>=255)r_col=255;
if(Num_col<=0)r_col=0;
if(Num_col>0 && Num_col<255)r_col=byr_colors[Num_col][0];
if(Num_col>=255)g_col=255;
if(Num_col<=0)g_col=0;
if(Num_col>0 && Num_col<255)g_col=byr_colors[Num_col][1];
if(Num_col>=255)b_col=255;
if(Num_col<=0)b_col=0;
if(Num_col>0 && Num_col<255)b_col=byr_colors[Num_col][2];
img_obp1->setPixel(-i,-j,qRgb(r_col,g_col,b_col));


// проверка
if(r_col>0)
count_r++;
LE_1->setText(str.setNum(count_r));
if(g_col>0)
count_g++;
LE_2->setText(str.setNum(count_g));
//


// верхний левый сектор окружности отображается
Num_col=acc_d->OUT_STR.Rastr[384-i][384+j];
if(Num_col>=255)r_col=255;
if(Num_col<=0)r_col=0;
if(Num_col>0 && Num_col<255)r_col=byr_colors[Num_col][0];
if(Num_col>=255)g_col=255;
if(Num_col<=0)g_col=0;
if(Num_col>0 && Num_col<255)g_col=byr_colors[Num_col][1];
if(Num_col>=255)b_col=255;
if(Num_col<=0)b_col=0;
if(Num_col>0 && Num_col<255)b_col=byr_colors[Num_col][2];
img_obp1->setPixel(-i,j,qRgb(r_col,g_col,b_col));

// проверка
if(r_col>0)
count_r++;
LE_1->setText(str.setNum(count_r));
if(g_col>0)
count_g++;
LE_2->setText(str.setNum(count_g));
//

Count_cel_obn=0;
int R1=0,R2=0;//расстояние до цели от центра окружности

for(int t=0;t<2;t++)
{
if(acc_d->OUT_STR.Mass_obn[t][0]==1)
{
Count_cel_obn++;

R1=(int)sqrt((float)((acc_d->OUT_STR.Otmetka[t][0]-384)*(acc_d->OUT_STR.Otmetka[t][0]-384) +(acc_d->OUT_STR.Otmetka[t][1]-384)*(acc_d->OUT_STR.Otmetka[t][1]-384)));
R2=(int)sqrt((float)((acc_d->OUT_STR.Otmetka[t][2]-384)*(acc_d->OUT_STR.Otmetka[t][2]-384) +(acc_d->OUT_STR.Otmetka[t][3]-384)*(acc_d->OUT_STR.Otmetka[t][3]-384)));
if(R1<=Radius && R2<=Radius && R1>0 && R2>0)
{
QRect rec1(acc_d->OUT_STR.Otmetka[t][0]-384,acc_d->OUT_STR.Otmetka[t][1]-384,3,3);
QRect rec2(acc_d->OUT_STR.Otmetka[t][2]-384,acc_d->OUT_STR.Otmetka[t][3]-384,3,3);
rgb_col=qRgb(255,255,255);
img_obp1->setPixel(acc_d->OUT_STR.Otmetka[t][0]-384,acc_d->OUT_STR.Otmetka[t][1]-384,rgb_col);
img_obp1->setPixel(acc_d->OUT_STR.Otmetka[t][0]-384+1,acc_d->OUT_STR.Otmetka[t][1]-384,rgb_col);
img_obp1->setPixel(acc_d->OUT_STR.Otmetka[t][0]-384-1,acc_d->OUT_STR.Otmetka[t][1]-384,rgb_col);
img_obp1->setPixel(acc_d->OUT_STR.Otmetka[t][0]-384,acc_d->OUT_STR.Otmetka[t][1]-384+1,rgb_col);
img_obp1->setPixel(acc_d->OUT_STR.Otmetka[t][0]-384+1,acc_d->OUT_STR.Otmetka[t][1]-384+1,rgb_col);
img_obp1->setPixel(acc_d->OUT_STR.Otmetka[t][0]-384-1,acc_d->OUT_STR.Otmetka[t][1]-384+1,rgb_col);
img_obp1->setPixel(acc_d->OUT_STR.Otmetka[t][0]-384,acc_d->OUT_STR.Otmetka[t][1]-384-1,rgb_col);
img_obp1->setPixel(acc_d->OUT_STR.Otmetka[t][0]-384+1,acc_d->OUT_STR.Otmetka[t][1]-384-1,rgb_col);
img_obp1->setPixel(acc_d->OUT_STR.Otmetka[t][0]-384-1,acc_d->OUT_STR.Otmetka[t][1]-384-1,rgb_col);

img_obp1->setPixel(acc_d->OUT_STR.Otmetka[t][2]-384,acc_d->OUT_STR.Otmetka[t][3]-384,rgb_col);
img_obp1->setPixel(acc_d->OUT_STR.Otmetka[t][2]-384+1,acc_d->OUT_STR.Otmetka[t][3]-384,rgb_col);
img_obp1->setPixel(acc_d->OUT_STR.Otmetka[t][2]-384-1,acc_d->OUT_STR.Otmetka[t][3]-384,rgb_col);
img_obp1->setPixel(acc_d->OUT_STR.Otmetka[t][2]-384,acc_d->OUT_STR.Otmetka[t][3]-384+1,rgb_col);
img_obp1->setPixel(acc_d->OUT_STR.Otmetka[t][2]-384+1,acc_d->OUT_STR.Otmetka[t][3]-384+1,rgb_col);
img_obp1->setPixel(acc_d->OUT_STR.Otmetka[t][2]-384-1,acc_d->OUT_STR.Otmetka[t][3]-384+1,rgb_col);
img_obp1->setPixel(acc_d->OUT_STR.Otmetka[t][2]-384,acc_d->OUT_STR.Otmetka[t][3]-384-1,rgb_col);
img_obp1->setPixel(acc_d->OUT_STR.Otmetka[t][2]-384+1,acc_d->OUT_STR.Otmetka[t][3]-384-1,rgb_col);
img_obp1->setPixel(acc_d->OUT_STR.Otmetka[t][2]-384-1,acc_d->OUT_STR.Otmetka[t][3]-384-1,rgb_col);
}
}
}
}
}

}
End_radius=Radius-1;
Count_krug++;
if(End_radius>=384)
LE_4->setText("end");
}
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #11 : Декабрь 07, 2011, 11:00 »

Что такое pr и frame_obp и зачем такой hack Непонимающий
Код
C++ (Qt)
frame_obp->paintEvent(pe);
Записан

Qt 5.11/4.8.7 (X11/Win)
BRE
Гость
« Ответ #12 : Декабрь 07, 2011, 11:35 »

Firefox, не нужно использовать и setPixel. Улыбающийся Ты при каждом вызове рассчитываешь адрес в буфере для указанных координат, а этого можно не делать.
Смотри небольшой пример:

Код
C++ (Qt)
#include <QImage>
#include <QColor>
 
const int ImageWidth  = 512;
const int ImageHeight = 512;
 
int main( int, char *[] )
{
       QImage img( ImageWidth, ImageHeight, QImage::Format_RGB32 );
 
       // Заливаем картинку Qt::Green
       QRgb *p = reinterpret_cast<QRgb *>( img.bits() );       // получаем указатель на начало буфера
       QRgb fillColor = QColor( Qt::green ).rgb();
       for( int i = 0; i < ImageWidth * ImageHeight; ++i )
               *p++ = fillColor;
 
       // Устанавливаем точку по координатам 10, 10
       int x = 10;
       int y = 10;
 
       QRgb *point = reinterpret_cast<QRgb *>( img.scanLine( y ) ) + x;        // другой способ получения адреса в буфере картинки
       QRgb pointColor = QColor( 20, 40, 60 ).rgb();           // r=20 g=40 b=60
       *point = pointColor;
 
       // Для того, что бы переместиться к следующей точке достаточно инкрементировать указатель point:
       // ++point
       // предыдущей:
       // --point
 
       // Для того, что бы переместиться к точке под текущей достаточно к указателю прибавить длину строки
       point += ImageWidth;
       *point = pointColor;
 
       img.save( "test.png" );
 
       return 0;
}
 

Для интереса можно сравнить скорость заливки картинки через буфер и через drawPoint/setPixe.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #13 : Декабрь 07, 2011, 11:44 »

Firefox, не нужно использовать и setPixel. Улыбающийся
На самом деле QImage::setPixel() тоже довольно-таки оптимизирован. И если пользоваться твоим способом, имхо, выигрыш будет минимальным)
Записан

Qt 5.11/4.8.7 (X11/Win)
BRE
Гость
« Ответ #14 : Декабрь 07, 2011, 11:48 »

На самом деле QImage::setPixel() тоже довольно-таки оптимизирован. И если пользоваться твоим способом, имхо, выигрыш будет минимальным)
Я веду к тому, что нужно изменять сам алгоритм формирования картинки и постараться сделать его линейным, т.е. выполнять заполнение по строкам.
А если прыгать от точки к точки, то мой вариант ничем не будет отличаться от setPixel или drawPixel. Улыбающийся
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.13 секунд. Запросов: 23.