Визуализация QGraphicsView в проблему времени кадра видео файла - PullRequest
0 голосов
/ 11 марта 2020

Я разрабатываю программу для создания 2D / 3D-анимации, в которой пользователь может создавать анимированные элементы на графической сцене c, после проектирования пользователю необходимо преобразовать анимацию в определенный c видеофайл для рендеринга. Я просто запускаю QTimer с ключом Qt :: PreciseTimer (когда анимация воспроизводится на QGraphicsView) и устанавливаю его интервал в 33 мс, чтобы получить 30 кадров в секунду, а в его сигнале времени ожидания я просто использую GraphicsView-> render, чтобы получить изображение того, что отображается на сцене, затем сохраните ее в файл, проблема в том, что интервал тайм-аута не точен, особенно если я перемещаю окно или делаю что-то еще в процессе преобразования! даже я переместил таймер в другой поток, но он не сработал!

Min Time: 33  Cur Time:  65 elapsed  64  Max Time: 65
Min Time: 32  Cur Time:  32 elapsed  31  Max Time: 65
Min Time: 32  Cur Time:  32 elapsed  32  Max Time: 65
Min Time: 32  Cur Time:  33 elapsed  32  Max Time: 65
Min Time: 32  Cur Time:  33 elapsed  33  Max Time: 65
Min Time: 32  Cur Time:  32 elapsed  31  Max Time: 65
Min Time: 32  Cur Time:  50 elapsed  49  Max Time: 65
Min Time: 22  Cur Time:  22 elapsed  22  Max Time: 65
Min Time: 22  Cur Time:  27 elapsed  27  Max Time: 65
Min Time: 22  Cur Time:  33 elapsed  32  Max Time: 65
Min Time: 22  Cur Time:  33 elapsed  32  Max Time: 65
Min Time: 22  Cur Time:  33 elapsed  32  Max Time: 65
Min Time: 22  Cur Time:  32 elapsed  32  Max Time: 65
Min Time: 22  Cur Time:  34 elapsed  32  Max Time: 65

для другого метода я использовал QTimeLine, который настроен на анимацию, и по его кадру FrameChanged я должен был найти точное время окончания кадра, чтобы сделать снимок, но опять же сигнал смены кадра тоже не точный!

Min Time: 0  Cur Time:  50  Max Time: 50
Min Time: 0  Cur Time:  32  Max Time: 50
Min Time: 0  Cur Time:  32  Max Time: 50
Min Time: 0  Cur Time:  33  Max Time: 50
Min Time: 0  Cur Time:  33  Max Time: 50
Min Time: 0  Cur Time:  33  Max Time: 50
Min Time: 0  Cur Time:  34  Max Time: 50
Min Time: 0  Cur Time:  32  Max Time: 50
Min Time: 0  Cur Time:  33  Max Time: 50
Min Time: 0  Cur Time:  25  Max Time: 50
Min Time: 0  Cur Time:  40  Max Time: 50
Min Time: 0  Cur Time:  33  Max Time: 50
Min Time: 0  Cur Time:  35  Max Time: 50
Min Time: 0  Cur Time:  31  Max Time: 50
Min Time: 0  Cur Time:  33  Max Time: 50
Min Time: 0  Cur Time:  33  Max Time: 50
Min Time: 0  Cur Time:  33  Max Time: 50
Min Time: 0  Cur Time:  33  Max Time: 50
Min Time: 0  Cur Time:  35  Max Time: 50
Min Time: 0  Cur Time:  31  Max Time: 50
Min Time: 0  Cur Time:  33  Max Time: 50
Min Time: 0  Cur Time:  32  Max Time: 50
Min Time: 0  Cur Time:  33  Max Time: 50
Min Time: 0  Cur Time:  32  Max Time: 50
Min Time: 0  Cur Time:  33  Max Time: 50

с этой проблемой, когда у меня есть анимированный элемент графика c, который движется линейно слева справа от сцены после преобразования его в видеофайл, когда я сгибаю файл, я вижу, что элемент перемещается на 3 пикселя в одном кадре и перемещается на 5 пикселей в другом кадре, тогда как он должен перемещать равные пиксели в каждом кадре !!

Я использую QElapsedTimer для точного определения промежутка времени между тайм-аутами каждого кадра,

в чем проблема? Есть ли лучший способ визуализации QGraphicsView в видео?

и есть ли другой способ не показывать что-либо на экране, когда вы просто хотите рендерить анимацию в файл? что-то вроде закадровой сцены?

какой-то фрагмент программы

void ZAnimator::onFrameChanged()
{
   timeta = elapsedTimera->elapsed();
   elapsedTimera->restart();

   if (timeta > maxtimeta)
       maxtimeta = timeta;

   if (timeta < mintimeta)
       mintimeta = timeta;

   qDebug() << "Min Time:" << mintimeta <<" Cur Time: " << timeta << " Max Time:" << maxtimeta;

    screenPixmap->fill(Qt::black);

    m_curSB->getGV()->render(screenPainter, screenPixmap->rect(),bRect);

    *tempImage = screenPixmap->toImage();

    imageData.push_back(*tempImage);
}

для другого решения, я переместил таймер и другой объект с простым слотом в новый поток, он работает хорошо когда я делаю вещи в слоте объекта в новом потоке, но как только я подключаю сигнал тайм-аута таймера к слоту моего основного потока GUI, снова слот в основном потоке срабатывает поздно и нерегулярно, а слот в объект, который находится в новом потоке, запускается в точное время! см

THR  32
GUI  32
THR  33
GUI  33
THR  34
GUI  34
THR  32
GUI  32
THR  33
THR  33
THR  33
THR  34
THR  32
GUI  190
GUI  0
GUI  0
GUI  0
GUI  0
THR  34
GUI  9
THR  33
...