From c523af9927c84cb8df6229dfe97d81c07ef67f79 Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Tue, 6 Jun 2017 12:51:16 +0200 Subject: [PATCH] Implement GIF support [read more] So, it works. Yay! Only one frame though. What could be the issue? Hrm. I'll look around. And open an issue in ginsweater/gif-h to try and work it out. I am amazed. --- recording/recordingcontroller.cpp | 20 +++++++++++++++----- recording/recordingcontroller.hpp | 1 + recording/recordingformats.cpp | 25 +++++++++++++++---------- recording/recordingpreview.cpp | 6 +++--- 4 files changed, 34 insertions(+), 18 deletions(-) diff --git a/recording/recordingcontroller.cpp b/recording/recordingcontroller.cpp index 7dc1a00..7dd376e 100644 --- a/recording/recordingcontroller.cpp +++ b/recording/recordingcontroller.cpp @@ -16,7 +16,7 @@ RecordingController::RecordingController() : timer(this) { } bool RecordingController::isRunning() { - return timer.isActive(); + return preview; } bool RecordingController::start(RecordingContext *context) { @@ -31,12 +31,17 @@ bool RecordingController::start(RecordingContext *context) { bool RecordingController::end() { if (!isRunning()) return false; area = QRect(); - preview->close(); + if (preview) { + preview->close(); + preview->deleteLater(); + } + preview = 0; WorkerContext *c = new WorkerContext; c->consumer = [&](QImage) { queue(_context->finalizer()); }; c->targetFormat = QImage::Format_Alpha8; c->pixmap = QPixmap(0, 0); + Worker::queue(c); frame = 0; time = 0; @@ -51,11 +56,15 @@ void RecordingController::queue(QByteArray arr) { void RecordingController::timeout() { if (isRunning()) { if (!_context->validator()) { - preview->close(); + if (preview) { + preview->close(); + preview->deleteLater(); + } frame = 0; time = 0; preview = 0; area = QRect(); + return; } time++; int localTime = time * timer.interval() - 3000; @@ -73,10 +82,11 @@ void RecordingController::timeout() { } long second = localTime / 1000 % 60; long minute = localTime / 60000; - preview->setTime(QString("%1:%2").arg(QString::number(minute)).arg(QString::number(second)), frame); + if (isRunning()) + preview->setTime(QString("%1:%2").arg(QString::number(minute)).arg(QString::number(second)), frame); } else { QMutexLocker l(&lock); - UploaderSingleton::inst().upload(uploadQueue.dequeue()); + if (!uploadQueue.isEmpty()) UploaderSingleton::inst().upload(uploadQueue.dequeue()); } } diff --git a/recording/recordingcontroller.hpp b/recording/recordingcontroller.hpp index 4b642b1..ca5374d 100644 --- a/recording/recordingcontroller.hpp +++ b/recording/recordingcontroller.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include diff --git a/recording/recordingformats.cpp b/recording/recordingformats.cpp index 70c9c11..0377b97 100644 --- a/recording/recordingformats.cpp +++ b/recording/recordingformats.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -10,6 +11,7 @@ #include #include #include +#include RecordingFormats::RecordingFormats(RecordingFormats::Format f) { QString path = QStandardPaths::writableLocation(QStandardPaths::TempLocation); @@ -25,24 +27,27 @@ RecordingFormats::RecordingFormats(RecordingFormats::Format f) { tmpDir.cd(name); switch (f) { case GIF: { - iFormat = QImage::Format_Alpha8; + iFormat = QImage::Format_RGBA8888; validator = [] { return true; }; consumer = [&](QImage img) { frames.push_back(img); }; finalizer = [&] { - if (frames.size() == 0) return QByteArray; - int f = 1; + if (frames.size() == 0) return QByteArray(); uint32_t d = 1000 / settings::settings().value("recording/framerate", 30).toInt(); - QImage startImg = frames[0]; + QImage &startImg = frames[0]; GifWriter writer; - GifBegin(&writer, tmpDir.absoluteFilePath("resulting.gif"), startImg.width(), startImg.height(), d) - - for (QImage &a : frames){ GifWriteFrame(writer, a.bits(), a.width(), a.height(), d) } QFile res( - tmpDir.absoluteFilePath("resulting.gif")); + GifBegin(&writer, tmpDir.absoluteFilePath("resulting.gif").toLocal8Bit().constData(), startImg.width(), + startImg.height(), d); + int i = 0; + for (QImage &a : frames) { + QByteArray alpha8((char *)a.bits(), a.byteCount()); + GifWriteFrame(&writer, (uint8_t *)alpha8.data(), a.width(), a.height(), d); + } + GifEnd(&writer); + QFile res(tmpDir.absoluteFilePath("resulting.gif")); if (!res.open(QFile::ReadOnly)) { - return QByteArray; + return QByteArray(); } QByteArray data = res.readAll(); - tmpDir.removeRecursively(); return data; }; break; diff --git a/recording/recordingpreview.cpp b/recording/recordingpreview.cpp index 91c53f0..ca3b20a 100644 --- a/recording/recordingpreview.cpp +++ b/recording/recordingpreview.cpp @@ -11,7 +11,6 @@ RecordingPreview::RecordingPreview(QRect area, QWidget *parent) : QWidget(parent recordingArea = area; setStyleSheet("background-color: rgba(0, 0, 0, 0.7);"); setAttribute(Qt::WA_TranslucentBackground); - setAttribute(Qt::WA_DeleteOnClose); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); setWindowFlags(windowFlags() | Qt::ToolTip | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint); QTimer::singleShot(0, [&] { @@ -45,6 +44,7 @@ void RecordingPreview::setPixmap(QPixmap map) { label->setPixmap(map); } void RecordingPreview::setTime(QString time, int frame) { - hintLabel->setText(QString("Time: ") + time + "\nFrame: " + QString::number(frame) - + "\nStop key: " + hotkeying::sequence("recordingstop")); + if (isVisible()) + hintLabel->setText(QString("Time: ") + time + "\nFrame: " + QString::number(frame) + + "\nStop key: " + hotkeying::sequence("recordingstop")); }