diff --git a/include/logoItem.h b/include/logoItem.h index fe72508cd2adbd9f5ca946208dda7d221441de55..e0465fcd626e4a8726aa1d42830a6a952bfb3dcd 100644 --- a/include/logoItem.h +++ b/include/logoItem.h @@ -19,44 +19,28 @@ #ifndef LOGOITEM_H #define LOGOITEM_H -#include <QGraphicsItem> +#include <QGraphicsObject> class Petrack; class LogoItem; +class QPropertyAnimation; -class Fader : public QObject -{ - Q_OBJECT -public: - Fader(); - void fadeOut(LogoItem *gi, int frames); -private slots: - void fadeOutStep(); - -public: - LogoItem *mLogoItem; - int mFrames; - double mStep; - QTimer *mTimer; -}; - -class LogoItem : public QGraphicsItem +class LogoItem : public QGraphicsObject { public: LogoItem(QWidget *wParent, QGraphicsItem *parent = nullptr); - QRectF boundingRect() const; + QRectF boundingRect() const override; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); - inline float getOpacity() const { return mOpacity; } - inline void setOpacity(float o) { mOpacity = o; } - void fadeOut(int frames = 100); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; + void fadeOut(); + void fadeIn(); private: - Petrack *mMainWindow; - QImage *mImage; - float mOpacity; - Fader fader; + Petrack *mMainWindow; + QImage *mImage; + QPropertyAnimation *mFadeAnimation; + static constexpr int mFadeDuration = 2'000; // in ms }; #endif diff --git a/src/imageItem.cpp b/src/imageItem.cpp index ca67c310bdaa4511cee149cf477d4ffa7bb8e3c4..3999f23ada48f726ffe623556500903b44efbc7f 100644 --- a/src/imageItem.cpp +++ b/src/imageItem.cpp @@ -66,8 +66,16 @@ void ImageItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*opti void ImageItem::setImage(QImage *img) { + if(img->isNull()) + { + mImage = nullptr; + setTransform(QTransform()); + mMainWindow->updateSceneRect(); + return; + } mImage = img; + QTransform matrix; matrix.translate( 1, 1); // FEHLER IN QT ????? noetig, damit trotz recognitionroiitem auch image auch ohne border komplett neu diff --git a/src/logoItem.cpp b/src/logoItem.cpp index 0d6a74e4e7707bb8c5849d3ce51d1e41a8524816..0b1d675bafb4b5cc5466a077bd3f13c90a8f703f 100644 --- a/src/logoItem.cpp +++ b/src/logoItem.cpp @@ -21,69 +21,14 @@ #include "petrack.h" #include <QApplication> -#include <QGraphicsScene> #include <QPainter> -#include <QTimer> -#include <ctime> -// minimale Zeit zwischen zwei Blendenstufen in Millisekunden -#define FRAME_INTERVAL 40 -Fader::Fader() +LogoItem::LogoItem(QWidget *wParent, QGraphicsItem *parent) : QGraphicsObject(parent) { - mTimer = nullptr; -} - -void Fader::fadeOut(LogoItem *lI, int frames) -{ - mLogoItem = lI; - if(frames < 1) - { - mFrames = 1; - } - else - { - mFrames = frames; - } - mStep = 1. / mFrames; - if(mTimer) // wenn fadeOut schon mal aufgerufen wurde; so wird nur ein QTimer maximal angelegt - { - delete mTimer; - } - mTimer = new QTimer(this); - connect(mTimer, SIGNAL(timeout()), this, SLOT(fadeOutStep())); - mTimer->start(FRAME_INTERVAL); // fuer 25fps -} - -void Fader::fadeOutStep() -{ - static clock_t lastTime = clock(); - - if(((double) (clock() - lastTime)) / CLOCKS_PER_SEC > - FRAME_INTERVAL * .001) // beschleunigen, wenn zu langsam ausgeblendet wird - { - mStep *= 2; - } - lastTime = clock(); - - if(mLogoItem->getOpacity() > 0.) - { - mLogoItem->setOpacity(mLogoItem->getOpacity() - mStep); - mLogoItem->scene()->update(); // ein neuzeichnen wird erwuenscht und irgendwann bei processEvents gemacht - qApp->processEvents(); - } - else - { - mLogoItem->setVisible(false); - mTimer->stop(); - } -} - -LogoItem::LogoItem(QWidget *wParent, QGraphicsItem *parent) : QGraphicsItem(parent) -{ - mOpacity = 1.0; - mMainWindow = (class Petrack *) wParent; - mImage = new QImage(":/logo"); // in icons.qrc definiert + mMainWindow = dynamic_cast<Petrack *>(wParent); + mImage = new QImage(":/logo"); // in icons.qrc definiert + mFadeAnimation = new QPropertyAnimation(this, "opacity", this); } QRectF LogoItem::boundingRect() const @@ -95,7 +40,7 @@ void LogoItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*optio { int w; int h; - if(mMainWindow->getImage()) + if(mMainWindow->getImage() && !mMainWindow->getImage()->isNull()) { w = (mMainWindow->getImage()->width()) / 2 - (mImage->width()) / 2 - mMainWindow->getImageBorderSize(); h = (mMainWindow->getImage()->height()) / 2 - (mImage->height()) / 2 - mMainWindow->getImageBorderSize(); @@ -105,20 +50,23 @@ void LogoItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*optio w = 0; h = 0; } - painter->setOpacity(mOpacity); painter->drawImage(w, h, *mImage); } -// logo wird langsam ausgeblendet -// blendgeschw ist rechnergeschwindigkeitsabhaengig -// qtimer waere auch eine mgl -// so wie hier, wird fkt, die nicht uber events/slots abgewickelt wird, -// wird zB bei projekt import die titelleiste erst nach dem ausblenden aktualisiert -// frame = anzahl der bildupdates, bis logo verschwunden ist -// mit opengl fkt fade schlecht -void LogoItem::fadeOut(int frames) +void LogoItem::fadeOut() +{ + mFadeAnimation->setStartValue(1); + mFadeAnimation->setEndValue(0); + mFadeAnimation->setDuration(mFadeDuration); + mFadeAnimation->start(); +} + +void LogoItem::fadeIn() { - fader.fadeOut(this, frames); + mFadeAnimation->setStartValue(0); + mFadeAnimation->setEndValue(1); + mFadeAnimation->setDuration(mFadeDuration); + mFadeAnimation->start(); } #include "moc_logoItem.cpp" diff --git a/src/petrack.cpp b/src/petrack.cpp index c71e5c01dbcb483c9a926a4aa4fecedda98bc6e5..02beaff12aa30e913c2e479d7916cb2f90c61829 100644 --- a/src/petrack.cpp +++ b/src/petrack.cpp @@ -366,12 +366,17 @@ void Petrack::updateSceneRect() { double iW = 0, iH = 0, bS = 0; - if(mImage) + if(mImage && !mImage->isNull()) { iW = mImage->width(); iH = mImage->height(); bS = getImageBorderSize(); } + else + { + mScene->setSceneRect(mScene->itemsBoundingRect()); + return; + } if(mControlWidget->getCalibCoordShow()) { @@ -558,9 +563,23 @@ void Petrack::openXml(QDomDocument &doc, bool openSeq) // open koennte am schluss passieren, dann wuerde nicht erst unveraendertes bild angezeigt, // dafuer koennte es aber sein, dass werte zb bei fx nicht einstellbar sind! mSeqFileName = seq; - if(openSeq && (seq != "")) + if(openSeq) { - openSequence(seq); // wenn leer, dann kommt abfrage hoch, welche datei; abbrechen, wenn aktuelle gewuenscht + if(seq != "") + { + openSequence(seq); + } + else + { + mAnimation->reset(); + mImg = cv::Mat(); + mImgFiltered = cv::Mat(); + delete mImage; + mImage = nullptr; + updateSequence(); + mLogoItem->ensureVisible(); + mLogoItem->fadeIn(); + } } mMissingFrames.setExecuted(missingFramesExecuted); @@ -926,14 +945,7 @@ void Petrack::openCameraLiveStream(int camID /* =-1*/) updateSequence(); updateWindowTitle(); mPlayerWidget->setFPS(mAnimation->getFPS()); - if(mOpenGLAct->isChecked()) - { - mLogoItem->fadeOut(1); - } - else - { - mLogoItem->fadeOut(50); - } + mLogoItem->fadeOut(); updateCoord(); mPlayerWidget->play(PlayerState::FORWARD); @@ -1003,14 +1015,7 @@ void Petrack::openSequence(QString fileName) // default fileName = "" updateSequence(); updateWindowTitle(); mPlayerWidget->setFPS(mAnimation->getFPS()); - if(mOpenGLAct->isChecked()) - { - mLogoItem->fadeOut(1); - } - else - { - mLogoItem->fadeOut(50); - } + mLogoItem->fadeOut(); updateCoord(); mMissingFrames.reset(); } @@ -1688,8 +1693,8 @@ void Petrack::antialias() void Petrack::opengl() { mView->setViewport(mOpenGLAct->isChecked() ? new QGLWidget(QGLFormat(QGL::SampleBuffers)) : new QWidget); - - // alten freigeben wegen new???? + // need full viewport update for fade out animation of LogoItem to work + mView->setViewportUpdateMode(QGraphicsView::FullViewportUpdate); } void Petrack::reset() { @@ -3550,22 +3555,35 @@ void Petrack::updateSequence() QImage *oldImage = mImage; QSize size = mAnimation->getSize(); - size.setWidth(size.width() + 2 * getImageBorderSize()); // border is inside the mImage! - size.setHeight(size.height() + 2 * getImageBorderSize()); - mImage = new QImage(size, QImage::Format_RGB888); // 32); //wird in updateImage gemacht + if(size != QSize{0, 0}) + { + size.setWidth(size.width() + 2 * getImageBorderSize()); // border is inside the mImage! + size.setHeight(size.height() + 2 * getImageBorderSize()); + } + mImage = new QImage(size, QImage::Format_RGB888); - // set roi for recognition if image size changes or roi is zero - // in oldImage steckt border drin, mIplImg->height zeigt noch auf altes ursprungsbild - // mRecognitionRoiItem->rect().width() != 0 && oldImage == NULL wenn projektdatei eingelesen wird!!!!! - if((mRecognitionRoiItem->rect().width() == 0) || // default while initialization, after that >= MIN_SIZE - (oldImage && ((oldImage->width() != mImage->width()) || (oldImage->height() != mImage->height())))) + + if(size == QSize{0, 0}) { - mRecognitionRoiItem->setRect(-getImageBorderSize(), -getImageBorderSize(), mImage->width(), mImage->height()); + // separate handling because border should currently be ignored + // will be applied when a sequence is loaded in + mRecognitionRoiItem->setRect(0, 0, 0, 0); + mTrackingRoiItem->setRect(0, 0, 0, 0); } - if((mTrackingRoiItem->rect().width() == 0) || - (oldImage && ((oldImage->width() != mImage->width()) || (oldImage->height() != mImage->height())))) + else { - mTrackingRoiItem->setRect(-getImageBorderSize(), -getImageBorderSize(), mImage->width(), mImage->height()); + const bool imageSizeChanged = oldImage && (oldImage->rect() != mImage->rect()); + // set roi for recognition if image size changes or roi is zero + if((mRecognitionRoiItem->rect().width() == 0) || imageSizeChanged) + { + mRecognitionRoiItem->setRect( + -getImageBorderSize(), -getImageBorderSize(), mImage->width(), mImage->height()); + } + + if((mTrackingRoiItem->rect().width() == 0) || imageSizeChanged) + { + mTrackingRoiItem->setRect(-getImageBorderSize(), -getImageBorderSize(), mImage->width(), mImage->height()); + } } cv::Size size2;