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.
This commit is contained in:
parent
6e36691f6c
commit
c523af9927
@ -16,7 +16,7 @@ RecordingController::RecordingController() : timer(this) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool RecordingController::isRunning() {
|
bool RecordingController::isRunning() {
|
||||||
return timer.isActive();
|
return preview;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RecordingController::start(RecordingContext *context) {
|
bool RecordingController::start(RecordingContext *context) {
|
||||||
@ -31,12 +31,17 @@ bool RecordingController::start(RecordingContext *context) {
|
|||||||
bool RecordingController::end() {
|
bool RecordingController::end() {
|
||||||
if (!isRunning()) return false;
|
if (!isRunning()) return false;
|
||||||
area = QRect();
|
area = QRect();
|
||||||
|
if (preview) {
|
||||||
preview->close();
|
preview->close();
|
||||||
|
preview->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
preview = 0;
|
preview = 0;
|
||||||
WorkerContext *c = new WorkerContext;
|
WorkerContext *c = new WorkerContext;
|
||||||
c->consumer = [&](QImage) { queue(_context->finalizer()); };
|
c->consumer = [&](QImage) { queue(_context->finalizer()); };
|
||||||
c->targetFormat = QImage::Format_Alpha8;
|
c->targetFormat = QImage::Format_Alpha8;
|
||||||
c->pixmap = QPixmap(0, 0);
|
c->pixmap = QPixmap(0, 0);
|
||||||
|
Worker::queue(c);
|
||||||
|
|
||||||
frame = 0;
|
frame = 0;
|
||||||
time = 0;
|
time = 0;
|
||||||
@ -51,11 +56,15 @@ void RecordingController::queue(QByteArray arr) {
|
|||||||
void RecordingController::timeout() {
|
void RecordingController::timeout() {
|
||||||
if (isRunning()) {
|
if (isRunning()) {
|
||||||
if (!_context->validator()) {
|
if (!_context->validator()) {
|
||||||
|
if (preview) {
|
||||||
preview->close();
|
preview->close();
|
||||||
|
preview->deleteLater();
|
||||||
|
}
|
||||||
frame = 0;
|
frame = 0;
|
||||||
time = 0;
|
time = 0;
|
||||||
preview = 0;
|
preview = 0;
|
||||||
area = QRect();
|
area = QRect();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
time++;
|
time++;
|
||||||
int localTime = time * timer.interval() - 3000;
|
int localTime = time * timer.interval() - 3000;
|
||||||
@ -73,10 +82,11 @@ void RecordingController::timeout() {
|
|||||||
}
|
}
|
||||||
long second = localTime / 1000 % 60;
|
long second = localTime / 1000 % 60;
|
||||||
long minute = localTime / 60000;
|
long minute = localTime / 60000;
|
||||||
|
if (isRunning())
|
||||||
preview->setTime(QString("%1:%2").arg(QString::number(minute)).arg(QString::number(second)), frame);
|
preview->setTime(QString("%1:%2").arg(QString::number(minute)).arg(QString::number(second)), frame);
|
||||||
} else {
|
} else {
|
||||||
QMutexLocker l(&lock);
|
QMutexLocker l(&lock);
|
||||||
UploaderSingleton::inst().upload(uploadQueue.dequeue());
|
if (!uploadQueue.isEmpty()) UploaderSingleton::inst().upload(uploadQueue.dequeue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
|
#include <QQueue>
|
||||||
#include <QRect>
|
#include <QRect>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
#include <QDebug>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
@ -10,6 +11,7 @@
|
|||||||
#include <platformbackend.hpp>
|
#include <platformbackend.hpp>
|
||||||
#include <settings.hpp>
|
#include <settings.hpp>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
RecordingFormats::RecordingFormats(RecordingFormats::Format f) {
|
RecordingFormats::RecordingFormats(RecordingFormats::Format f) {
|
||||||
QString path = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
|
QString path = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
|
||||||
@ -25,24 +27,27 @@ RecordingFormats::RecordingFormats(RecordingFormats::Format f) {
|
|||||||
tmpDir.cd(name);
|
tmpDir.cd(name);
|
||||||
switch (f) {
|
switch (f) {
|
||||||
case GIF: {
|
case GIF: {
|
||||||
iFormat = QImage::Format_Alpha8;
|
iFormat = QImage::Format_RGBA8888;
|
||||||
validator = [] { return true; };
|
validator = [] { return true; };
|
||||||
consumer = [&](QImage img) { frames.push_back(img); };
|
consumer = [&](QImage img) { frames.push_back(img); };
|
||||||
finalizer = [&] {
|
finalizer = [&] {
|
||||||
if (frames.size() == 0) return QByteArray;
|
if (frames.size() == 0) return QByteArray();
|
||||||
int f = 1;
|
|
||||||
uint32_t d = 1000 / settings::settings().value("recording/framerate", 30).toInt();
|
uint32_t d = 1000 / settings::settings().value("recording/framerate", 30).toInt();
|
||||||
QImage startImg = frames[0];
|
QImage &startImg = frames[0];
|
||||||
GifWriter writer;
|
GifWriter writer;
|
||||||
GifBegin(&writer, tmpDir.absoluteFilePath("resulting.gif"), startImg.width(), startImg.height(), d)
|
GifBegin(&writer, tmpDir.absoluteFilePath("resulting.gif").toLocal8Bit().constData(), startImg.width(),
|
||||||
|
startImg.height(), d);
|
||||||
for (QImage &a : frames){ GifWriteFrame(writer, a.bits(), a.width(), a.height(), d) } QFile res(
|
int i = 0;
|
||||||
tmpDir.absoluteFilePath("resulting.gif"));
|
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)) {
|
if (!res.open(QFile::ReadOnly)) {
|
||||||
return QByteArray;
|
return QByteArray();
|
||||||
}
|
}
|
||||||
QByteArray data = res.readAll();
|
QByteArray data = res.readAll();
|
||||||
tmpDir.removeRecursively();
|
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
|
@ -11,7 +11,6 @@ RecordingPreview::RecordingPreview(QRect area, QWidget *parent) : QWidget(parent
|
|||||||
recordingArea = area;
|
recordingArea = area;
|
||||||
setStyleSheet("background-color: rgba(0, 0, 0, 0.7);");
|
setStyleSheet("background-color: rgba(0, 0, 0, 0.7);");
|
||||||
setAttribute(Qt::WA_TranslucentBackground);
|
setAttribute(Qt::WA_TranslucentBackground);
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
|
||||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
setWindowFlags(windowFlags() | Qt::ToolTip | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
|
setWindowFlags(windowFlags() | Qt::ToolTip | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
|
||||||
QTimer::singleShot(0, [&] {
|
QTimer::singleShot(0, [&] {
|
||||||
@ -45,6 +44,7 @@ void RecordingPreview::setPixmap(QPixmap map) {
|
|||||||
label->setPixmap(map);
|
label->setPixmap(map);
|
||||||
}
|
}
|
||||||
void RecordingPreview::setTime(QString time, int frame) {
|
void RecordingPreview::setTime(QString time, int frame) {
|
||||||
|
if (isVisible())
|
||||||
hintLabel->setText(QString("Time: ") + time + "\nFrame: " + QString::number(frame)
|
hintLabel->setText(QString("Time: ") + time + "\nFrame: " + QString::number(frame)
|
||||||
+ "\nStop key: " + hotkeying::sequence("recordingstop"));
|
+ "\nStop key: " + hotkeying::sequence("recordingstop"));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user