This commit is contained in:
寂静的羽夏 2022-07-26 19:49:53 +08:00
parent 717f0ea858
commit dbc186f09a
10 changed files with 204 additions and 20 deletions

View File

@ -1,6 +1,48 @@
#include "createreversedialog.h" #include "createreversedialog.h"
#include <QShortcut>
CreateReverseDialog::CreateReverseDialog() CreateReverseDialog::CreateReverseDialog(int max, DMainWindow *parent)
{ : DDialog(parent) {
setWindowTitle(tr("CreateReverseDialog"));
max--; //转为索引
addContent(new DLabel(tr("Start"), this));
addSpacing(3);
sbfrom = new DSpinBox(this);
sbfrom->setMinimum(0);
sbfrom->setValue(0);
sbfrom->setMaximum(max - 1);
addContent(sbfrom);
addSpacing(5);
addContent(new DLabel(tr("End"), this));
sbto = new DSpinBox(this);
sbto->setMinimum(1);
sbto->setValue(max);
sbto->setMaximum(max);
addContent(sbto);
addSpacing(20);
auto dbbox = new DDialogButtonBox(
DDialogButtonBox::Ok | DDialogButtonBox::Cancel, this);
connect(dbbox, &DDialogButtonBox::accepted, this,
&CreateReverseDialog::on_accept);
connect(dbbox, &DDialogButtonBox::rejected, this,
&CreateReverseDialog::on_reject);
auto key = QKeySequence(Qt::Key_Return);
auto s = new QShortcut(key, this);
connect(s, &QShortcut::activated, this, &CreateReverseDialog::on_accept);
addContent(dbbox);
}
ReverseResult CreateReverseDialog::getResult() { return res; }
void CreateReverseDialog::on_accept() {
res.start = sbfrom->value();
res.end = sbto->value();
done(1);
}
void CreateReverseDialog::on_reject() { done(0); }
void CreateReverseDialog::closeEvent(QCloseEvent *event) {
Q_UNUSED(event);
done(0);
} }

View File

@ -1,11 +1,34 @@
#ifndef CREATEREVERSEDIALOG_H #ifndef CREATEREVERSEDIALOG_H
#define CREATEREVERSEDIALOG_H #define CREATEREVERSEDIALOG_H
#include <DDialog>
#include <DDialogButtonBox>
#include <DLabel>
#include <DMainWindow>
#include <DSpinBox>
class CreateReverseDialog DWIDGET_USE_NAMESPACE
{
public: struct ReverseResult {
CreateReverseDialog(); int start = -1;
int end = -1;
}; };
#endif // CREATEREVERSEDIALOG_H class CreateReverseDialog : public DDialog {
public:
CreateReverseDialog(int max, DMainWindow *parent = nullptr);
ReverseResult getResult();
private:
void on_accept();
void on_reject();
protected:
void closeEvent(QCloseEvent *event) override;
private:
DSpinBox *sbfrom, *sbto;
ReverseResult res;
};
#endif // CREATEREVERSEDIALOG_H

View File

@ -1,4 +1,6 @@
#include "Dialog/mainwindow.h" #include "Dialog/mainwindow.h"
#include "Dialog/createreversedialog.h"
#include "Dialog/reduceframedialog.h"
#include "Dialog/sponsordialog.h" #include "Dialog/sponsordialog.h"
#include <DInputDialog> #include <DInputDialog>
#include <DMenu> #include <DMenu>
@ -396,11 +398,8 @@ void MainWindow::on_del() {
indices.append(item.row()); indices.append(item.row());
} }
std::sort(indices.begin(), indices.end()); std::sort(indices.begin(), indices.end());
int offset = 0; for (auto p = indices.rbegin(); p != indices.rend(); p++) {
for (auto item : indices) { gif.removeFrame(*p);
auto off = item - offset;
gif.removeFrame(off);
offset++;
} }
for (int i = indices.first(); i < imglist->count(); i++) { for (int i = indices.first(); i < imglist->count(); i++) {
imglist->item(i)->setText( imglist->item(i)->setText(
@ -464,7 +463,13 @@ void MainWindow::on_next() {
void MainWindow::on_endframe() { imglist->setCurrentRow(imglist->count() - 1); } void MainWindow::on_endframe() { imglist->setCurrentRow(imglist->count() - 1); }
void MainWindow::on_decreaseframe() {} void MainWindow::on_decreaseframe() {
ReduceFrameDialog d(imglist->count(), this);
if (d.exec()) {
auto res = d.getResult();
gif.reduceFrame(res.start, res.end, res.stepcount);
}
}
void MainWindow::on_delbefore() { void MainWindow::on_delbefore() {
auto len = imglist->currentRow(); auto len = imglist->currentRow();
@ -551,7 +556,13 @@ void MainWindow::on_moveright() {
} }
} }
void MainWindow::on_createreverse() {} void MainWindow::on_createreverse() {
CreateReverseDialog d(imglist->count(), this);
if (d.exec()) {
auto res = d.getResult();
gif.createReverse(res.start, res.end);
}
}
void MainWindow::on_setdelay() { void MainWindow::on_setdelay() {
auto indices = imglist->selectionModel()->selectedRows(); auto indices = imglist->selectionModel()->selectedRows();

View File

@ -1,5 +1,57 @@
#include "reduceframedialog.h" #include "reduceframedialog.h"
#include <QShortcut>
ReduceFrameDialog::ReduceFrameDialog(DMainWindow *parent) : DDialog(parent) {} ReduceFrameDialog::ReduceFrameDialog(int max, DMainWindow *parent)
: DDialog(parent) {
setWindowTitle(tr("ReduceFrameDialog"));
addContent(new DLabel(tr("ReduceCount"), this));
addSpacing(3);
max--; //转为索引
sbcount = new DSpinBox(this);
sbcount->setMinimum(1);
sbcount->setValue(1);
sbcount->setMaximum(max - 1);
addContent(sbcount);
addSpacing(5);
addContent(new DLabel(tr("ReduceStart"), this));
addSpacing(3);
sbfrom = new DSpinBox(this);
sbfrom->setMinimum(0);
sbfrom->setValue(0);
sbfrom->setMaximum(max - 1);
addContent(sbfrom);
addSpacing(5);
addContent(new DLabel(tr("ReduceEnd"), this));
sbto = new DSpinBox(this);
sbto->setMinimum(1);
sbto->setValue(max);
sbto->setMaximum(max);
addContent(sbto);
addSpacing(20);
auto dbbox = new DDialogButtonBox(
DDialogButtonBox::Ok | DDialogButtonBox::Cancel, this);
connect(dbbox, &DDialogButtonBox::accepted, this,
&ReduceFrameDialog::on_accept);
connect(dbbox, &DDialogButtonBox::rejected, this,
&ReduceFrameDialog::on_reject);
auto key = QKeySequence(Qt::Key_Return);
auto s = new QShortcut(key, this);
connect(s, &QShortcut::activated, this, &ReduceFrameDialog::on_accept);
addContent(dbbox);
}
void ReduceFrameDialog::closeEvent(QCloseEvent *event) {} ReduceResult ReduceFrameDialog::getResult() { return res; }
void ReduceFrameDialog::on_accept() {
res.start = sbfrom->value();
res.end = sbto->value();
res.stepcount = sbcount->value();
done(1);
}
void ReduceFrameDialog::on_reject() { done(0); }
void ReduceFrameDialog::closeEvent(QCloseEvent *event) {
Q_UNUSED(event);
done(0);
}

View File

@ -9,9 +9,16 @@
DWIDGET_USE_NAMESPACE DWIDGET_USE_NAMESPACE
struct ReduceResult {
int start = -1;
int end = -1;
int stepcount = 1;
};
class ReduceFrameDialog : public DDialog { class ReduceFrameDialog : public DDialog {
public: public:
ReduceFrameDialog(DMainWindow *parent = nullptr); ReduceFrameDialog(int max, DMainWindow *parent = nullptr);
ReduceResult getResult();
private: private:
void on_accept(); void on_accept();
@ -21,8 +28,10 @@ protected:
void closeEvent(QCloseEvent *event) override; void closeEvent(QCloseEvent *event) override;
private: private:
DSpinBox *sbinterval; DSpinBox *sbcount;
DSpinBox *sbfrom, *sbto; DSpinBox *sbfrom, *sbto;
ReduceResult res;
}; };
#endif // REDUCEFRAMEDIALOG_H #endif // REDUCEFRAMEDIALOG_H

View File

@ -105,6 +105,21 @@ int GifHelper::merge(QString &gif, int index) {
return res; return res;
} }
void GifHelper::reduceFrame(int from, int to, int step) {
m_gif.reduceFrame(from, to, step); //输出的删除索引为倒序的
generatePreview();
emit frameRefreshAll();
}
void GifHelper::createReverse(int from, int to) {
m_gif.createReverse(from, to);
auto len = to - from + 1;
for (auto i = from; i <= to; i++) {
m_preview.insert(to + 1, m_gif.frame(i));
}
emit frameMerge(to + 1, len);
}
void GifHelper::generatePreview() { void GifHelper::generatePreview() {
m_preview.clear(); m_preview.clear();
auto len = m_gif.frameCount(); auto len = m_gif.frameCount();

View File

@ -34,6 +34,9 @@ public:
bool applymodel(QString filename, QVector<int> indices); bool applymodel(QString filename, QVector<int> indices);
int merge(QString &gif, int index = -1); int merge(QString &gif, int index = -1);
void reduceFrame(int from, int to, int step);
void createReverse(int from, int to);
signals: signals:
void frameRemoved(int index); void frameRemoved(int index);
void frameRefreshAll(); void frameRefreshAll();

View File

@ -148,6 +148,32 @@ int GifImage::merge(QString gif, int index) {
return int(cimgs.size()); return int(cimgs.size());
} }
void GifImage::reduceFrame(int from, int to, int step) {
auto len = frameCount();
if (from < 0 || from >= to || to >= len || step >= len - 1)
return;
for (auto i = from + 1; i <= to; i += step) {
removeFrame(i);
to--;
}
auto q = uint(step) + 1;
for (auto &item : m_frames) {
item.animationDelay(item.animationDelay() * (q + 1) / q);
}
}
void GifImage::createReverse(int from, int to) {
auto len = frameCount();
if (from < 0 || from >= to || to >= len)
return;
std::vector<Magick::Image> tmp(ulong(to - from + 1));
std::reverse_copy(m_frames.begin() + from, m_frames.begin() + to,
tmp.begin());
m_frames.insert(m_frames.end(), tmp.begin(), tmp.end());
}
void GifImage::waitThreadPool() { void GifImage::waitThreadPool() {
while (!QThreadPool::globalInstance()->waitForDone(100 / 6)) while (!QThreadPool::globalInstance()->waitForDone(100 / 6))
QApplication::processEvents(); QApplication::processEvents();

View File

@ -113,6 +113,9 @@ public:
bool applymodel(QString filename, QVector<int> indices); bool applymodel(QString filename, QVector<int> indices);
int merge(QString gif, int index = -1); int merge(QString gif, int index = -1);
void reduceFrame(int from, int to, int step);
void createReverse(int from, int to);
private: private:
void waitThreadPool(); void waitThreadPool();
QImage Image2QImage(const Magick::Image &img); QImage Image2QImage(const Magick::Image &img);

View File

@ -1,4 +1,4 @@
#include "mainwindow.h" #include "Dialog/mainwindow.h"
#include <DApplication> #include <DApplication>
#include <DApplicationSettings> #include <DApplicationSettings>
#include <DTitlebar> #include <DTitlebar>