This commit is contained in:
寂静的羽夏 2022-08-19 18:44:03 +08:00
parent d65a4273ff
commit b50ee48459
9 changed files with 45 additions and 16 deletions

View File

@ -752,12 +752,15 @@ bool MainWindow::saveGif(QString filename) {
if (gifsaver.open(filename.toStdString(), uint16_t(size.width()),
uint16_t(size.height()), _quality, false, 0)) {
QApplication::processEvents();
auto frames = gif.frames();
auto pframe = frames.begin();
auto eframe = frames.end();
auto img = pframe->image;
QApplication::processEvents();
gifsaver.push(GifEncoder::PIXEL_FORMAT_RGBA, img.constBits(), 0, 0,
img.width(), img.height(), pframe->delayTime / 10);
@ -776,6 +779,7 @@ bool MainWindow::saveGif(QString filename) {
if (memcmp(o, d, size_t(bpl))) {
break;
}
QApplication::processEvents();
}
for (y0 = ls - 1; y0 > y; y0--) {
@ -784,6 +788,7 @@ bool MainWindow::saveGif(QString filename) {
if (memcmp(o, d, size_t(bpl))) {
break;
}
QApplication::processEvents();
}
QTransform trans;
@ -800,6 +805,7 @@ bool MainWindow::saveGif(QString filename) {
if (memcmp(o, d, size_t(bpl))) {
break;
}
QApplication::processEvents();
}
for (x0 = ls - 1; x0 > x; x0--) {
auto o = rlimg.constScanLine(x0);
@ -807,6 +813,7 @@ bool MainWindow::saveGif(QString filename) {
if (memcmp(o, d, size_t(bpl))) {
break;
}
QApplication::processEvents();
}
auto timg = img.copy(adjustImageSize(x, y, x0 - x + 1, y0 - y + 1));
@ -816,7 +823,7 @@ bool MainWindow::saveGif(QString filename) {
}
gifsaver.close();
setSaved(true);
undo.setClean();
return true;
}
return false;
@ -825,7 +832,7 @@ bool MainWindow::saveGif(QString filename) {
QRect MainWindow::adjustImageSize(int x, int y, int w, int h) {
// 由于保存图像使用神经网络算法,图片有最小值限制,这里命名为 OFFSET
// 这里为实验值
#define OFFSET 16
#define OFFSET 32
if (w <= OFFSET) {
if (x - OFFSET > 0) {
x -= OFFSET;
@ -908,7 +915,7 @@ void MainWindow::on_del() {
for (auto item : imglist->selectionModel()->selectedIndexes()) {
indices.append(item.row());
}
undo.push(new RemoveFrameCommand(&gif, indices));
undo.push(new RemoveFrameCommand(&gif, imglist, indices));
}
void MainWindow::on_selall() {
@ -1153,7 +1160,7 @@ void MainWindow::on_cut() {
sel.append(frames[i.row()]);
}
ClipBoardHelper::setImageFrames(sel);
undo.push(new RemoveFrameCommand(&gif, indices));
undo.push(new RemoveFrameCommand(&gif, imglist, indices));
}
void MainWindow::on_paste() {

View File

@ -1,12 +1,11 @@
#include "waitingdialog.h"
#include <DWidgetUtil>
#include <QApplication>
#include <QHideEvent>
#include <QShowEvent>
#include <QThread>
WaitingDialog::WaitingDialog(DMainWindow *parent) : DDialog(parent) {
moveToThread(new QThread(this)); // 启用一个新线程,防止界面卡死
setWindowTitle(tr("PleaseWait"));
addSpacing(50);
pro = new DWaterProgress(this);

View File

@ -1,4 +1,5 @@
#include "gifdecoder.h"
#include <QApplication>
#include <QFile>
#include <QIODevice>
#include <QPainter>
@ -49,6 +50,8 @@ bool GifDecoder::load(const QString &fileName) {
pimg.fill(Qt::transparent);
for (int idx = 0; idx < gifFile->ImageCount; ++idx) {
QApplication::processEvents();
SavedImage gifImage = gifFile->SavedImages[idx];
int top = gifImage.ImageDesc.Top;
int left = gifImage.ImageDesc.Left;
@ -92,12 +95,15 @@ bool GifDecoder::load(const QString &fileName) {
memcpy(image.scanLine(row), gifImage.RasterBits + line * width,
size_t(width));
line++;
QApplication::processEvents();
}
QApplication::processEvents();
}
} else {
for (int row = 0; row < height; row++) {
memcpy(image.scanLine(row), gifImage.RasterBits + row * width,
size_t(width));
QApplication::processEvents();
}
}

View File

@ -12,6 +12,8 @@
#include <string>
#include <vector>
#include <QApplication>
#define GifAddExtensionBlockFor(a, func, len, data) \
GifAddExtensionBlock(&((a)->ExtensionBlockCount), &((a)->ExtensionBlocks), \
func, len, data)
@ -217,6 +219,7 @@ bool GifEncoder::close() {
encodeFrame(finfo.x, finfo.y, finfo.w, finfo.h, finfo.delay, nullptr,
rasterBits);
QApplication::processEvents();
}
}

View File

@ -1,8 +1,9 @@
#include "removeframecommand.h"
RemoveFrameCommand::RemoveFrameCommand(GifDecoder *helper, QVector<int> &frames,
RemoveFrameCommand::RemoveFrameCommand(GifDecoder *helper, QListWidget *listw,
QVector<int> &frames,
QUndoCommand *parent)
: QUndoCommand(parent), gif(helper) {
: QUndoCommand(parent), gif(helper), m_list(listw) {
indices = frames;
std::sort(indices.begin(), indices.end(), std::greater<int>());
@ -16,11 +17,18 @@ void RemoveFrameCommand::undo() {
for (auto i : indices) {
gif->insertFrame(i, imgs[i]);
}
gif->frameRefreshLabel(*indices.end());
auto l = indices.last();
gif->frameRefreshLabel(l);
m_list->setCurrentRow(l);
}
void RemoveFrameCommand::redo() {
for (auto p = indices.rbegin(); p < indices.rend(); p++)
gif->removeFrame(*p);
gif->frameRefreshLabel(*indices.end());
auto l = indices.last();
gif->frameRefreshLabel(l);
auto c = gif->frameCount();
if (l >= c)
l = c;
m_list->setCurrentRow(l);
}

View File

@ -2,19 +2,21 @@
#define REMOVEFRAMECOMMAND_H
#include "GifImage/decoder/gifdecoder.h"
#include <QListWidget>
#include <QMap>
#include <QUndoCommand>
class RemoveFrameCommand : public QUndoCommand {
public:
RemoveFrameCommand(GifDecoder *helper, QVector<int> &frames,
QUndoCommand *parent = nullptr);
RemoveFrameCommand(GifDecoder *helper, QListWidget *listw,
QVector<int> &frames, QUndoCommand *parent = nullptr);
void undo() override;
void redo() override;
protected:
GifDecoder *gif;
QListWidget *m_list;
QVector<int> indices;
QVector<QGifFrameInfoData> imgs;
};

View File

@ -6,12 +6,12 @@
### GIF 库
&emsp;&emsp;本软件基于两个库修改定制而得,一个负责读:`QtGifImage`,另一个负责写:`BurstLinker`。
&emsp;&emsp;`BurstLinker`是`Android`平台上一个`GIF`编码库,还不错。它的底层实现是`C++`,所以我可以进行略微的修改定制得到,仓库 [链接](https://github.com/yutianzuo/BurstLinker) 。
&emsp;&emsp;本软件基于两个库修改定制而得,一个负责读:`QtGifImage`,另一个负责写:`GifEncoder`。
&emsp;&emsp;`QtGifImage`是`Qt`上的`GIF`读写库,可以将`GIF`解析为`QImage`序列,基于`giflib`。这个我改动比较大,只保留了读取部分,并与我的软件做了适配(这个库写`GIF`图片的质量有点太差),仓库 [链接](https://github.com/jiangcaiyang/QtGifImage) 。
&emsp;&emsp;`GifEncoder`是一个能够提供高质量编码的`GIF`编码库,使用神经网络算法。为了实现基本的压缩,我进行略微的修改定制得到,仓库 [链接](https://github.com/xiaozhuai/GifEncoder) 。
### 编译安装
&emsp;&emsp;由于本软件依赖`Qt`和`DTK``DTK`直接在深度应用商店下载就行了。安装完毕后,打开项目,你就可以直接编译该软件了。

View File

@ -42,7 +42,7 @@ int main(int argc, char *argv[]) {
a.setOrganizationName("WingCloud");
a.setApplicationName("WingGifEditor");
a.setApplicationVersion("1.1.0");
a.setApplicationVersion("1.1.1");
a.setProductIcon(QIcon(":/images/icon.png"));
a.setProductName(QObject::tr("WingGifEditor"));
a.setApplicationDescription(

View File

@ -13,3 +13,7 @@ v1.0.0:
v1.1.0:
1. 修复已知问题,优化用户体验
2. 修复等待弹窗提示被卡死的 Bug
v1.1.1:
1. 使等待弹窗提示动画更加流畅
2. 增大神经网络参数,以解决部分 GIF 图片无法正常保存的问题