This commit is contained in:
寂静的羽夏 2022-07-25 18:37:57 +08:00
parent 9592ca0586
commit b63df6f793
29 changed files with 438 additions and 124 deletions

View File

@ -52,7 +52,7 @@ GifMakeMapObject(int ColorCount, const GifColorType *ColorMap)
return ((ColorMapObject *) NULL);
}
Object->Colors = (GifColorType *)calloc(ColorCount, sizeof(GifColorType));
Object->Colors = (GifColorType *)calloc((ulong)ColorCount, sizeof(GifColorType));
if (Object->Colors == (GifColorType *) NULL) {
free(Object);
return ((ColorMapObject *) NULL);
@ -63,7 +63,7 @@ GifMakeMapObject(int ColorCount, const GifColorType *ColorMap)
if (ColorMap != NULL) {
memcpy((char *)Object->Colors,
(char *)ColorMap, ColorCount * sizeof(GifColorType));
(const char *)ColorMap, (ulong)ColorCount * sizeof(GifColorType));
}
return (Object);
@ -158,11 +158,11 @@ GifUnionColorMap(const ColorMapObject *ColorIn1,
break;
if (j < ColorIn1->ColorCount)
ColorTransIn2[i] = j; /* color exists in Color1 */
ColorTransIn2[i] = (GifPixelType)j; /* color exists in Color1 */
else {
/* Color is new - copy it to a new slot: */
ColorUnion->Colors[CrntSlot] = ColorIn2->Colors[i];
ColorTransIn2[i] = CrntSlot++;
ColorTransIn2[i] = (GifPixelType)CrntSlot++;
}
}
@ -188,7 +188,7 @@ GifUnionColorMap(const ColorMapObject *ColorIn1,
/* perhaps we can shrink the map? */
if (RoundUpTo < ColorUnion->ColorCount)
ColorUnion->Colors = (GifColorType *)realloc(Map,
sizeof(GifColorType) * RoundUpTo);
sizeof(GifColorType) * (ulong)RoundUpTo);
}
ColorUnion->ColorCount = RoundUpTo;
@ -227,7 +227,7 @@ GifAddExtensionBlock(int *ExtensionBlockCount,
else
*ExtensionBlocks = (ExtensionBlock *)realloc(*ExtensionBlocks,
sizeof(ExtensionBlock) *
(*ExtensionBlockCount + 1));
(ulong)(*ExtensionBlockCount + 1));
if (*ExtensionBlocks == NULL)
return (GIF_ERROR);
@ -235,8 +235,8 @@ GifAddExtensionBlock(int *ExtensionBlockCount,
ep = &(*ExtensionBlocks)[(*ExtensionBlockCount)++];
ep->Function = Function;
ep->ByteCount=Len;
ep->Bytes = (GifByteType *)malloc(ep->ByteCount);
ep->ByteCount=(int)Len;
ep->Bytes = (GifByteType *)malloc((ulong)ep->ByteCount);
if (ep->Bytes == NULL)
return (GIF_ERROR);
@ -315,7 +315,7 @@ GifMakeSavedImage(GifFileType *GifFile, const SavedImage *CopyFrom)
GifFile->SavedImages = (SavedImage *)malloc(sizeof(SavedImage));
else
GifFile->SavedImages = (SavedImage *)realloc(GifFile->SavedImages,
sizeof(SavedImage) * (GifFile->ImageCount + 1));
sizeof(SavedImage) * (ulong)(GifFile->ImageCount + 1));
if (GifFile->SavedImages == NULL)
return ((SavedImage *)NULL);
@ -345,27 +345,27 @@ GifMakeSavedImage(GifFileType *GifFile, const SavedImage *CopyFrom)
/* next, the raster */
sp->RasterBits = (unsigned char *)malloc(sizeof(GifPixelType) *
CopyFrom->ImageDesc.Height *
CopyFrom->ImageDesc.Width);
(ulong)(CopyFrom->ImageDesc.Height *
CopyFrom->ImageDesc.Width));
if (sp->RasterBits == NULL) {
FreeLastSavedImage(GifFile);
return (SavedImage *)(NULL);
}
memcpy(sp->RasterBits, CopyFrom->RasterBits,
sizeof(GifPixelType) * CopyFrom->ImageDesc.Height *
CopyFrom->ImageDesc.Width);
sizeof(GifPixelType) * (ulong)(CopyFrom->ImageDesc.Height *
CopyFrom->ImageDesc.Width));
/* finally, the extension blocks */
if (sp->ExtensionBlocks != NULL) {
sp->ExtensionBlocks = (ExtensionBlock *)malloc(
sizeof(ExtensionBlock) *
CopyFrom->ExtensionBlockCount);
(ulong)CopyFrom->ExtensionBlockCount);
if (sp->ExtensionBlocks == NULL) {
FreeLastSavedImage(GifFile);
return (SavedImage *)(NULL);
}
memcpy(sp->ExtensionBlocks, CopyFrom->ExtensionBlocks,
sizeof(ExtensionBlock) * CopyFrom->ExtensionBlockCount);
sizeof(ExtensionBlock) *(ulong)(CopyFrom->ExtensionBlockCount));
}
}

View File

@ -27,6 +27,7 @@
#include <QDebug>
#include <QFile>
#include <QImage>
#include <QPainter>
#include <QScopedPointer>
namespace {
@ -99,8 +100,8 @@ QSize QGifImagePrivate::getCanvasSize() const {
int width = -1;
int height = -1;
for (QGifFrameInfoData info : frameInfos) {
int w = info.image.width() + info.offset.x();
int h = info.image.height() + info.offset.y();
int w = info.image.width();
int h = info.image.height();
if (w > width)
width = w;
if (h > height)
@ -144,6 +145,8 @@ bool QGifImagePrivate::load(QIODevice *device) {
if (DGifSlurp(gifFile) == GIF_ERROR)
return false;
frameInfos.clear(); // fixed by wingsummer
canvasSize.setWidth(gifFile->SWidth);
canvasSize.setHeight(gifFile->SHeight);
if (gifFile->SColorMap) {
@ -152,6 +155,8 @@ bool QGifImagePrivate::load(QIODevice *device) {
bgColor = QColor(globalColorTable[gifFile->SBackGroundColor]);
}
QImage lastimg;
for (int idx = 0; idx < gifFile->ImageCount; ++idx) {
SavedImage gifImage = gifFile->SavedImages[idx];
int top = gifImage.ImageDesc.Top;
@ -178,7 +183,7 @@ bool QGifImagePrivate::load(QIODevice *device) {
frameInfo.transparentColor = colorTable[transColorIndex];
frameInfo.delayTime = gcb.DelayTime * 10; // convert to milliseconds
frameInfo.interlace = gifImage.ImageDesc.Interlace;
frameInfo.offset = QPoint(left, top);
// frameInfo.offset = QPoint(left, top);
QImage image(width, height, QImage::Format_Indexed8);
image.setOffset(QPoint(left, top)); // Maybe useful for some users.
@ -223,7 +228,19 @@ bool QGifImagePrivate::load(QIODevice *device) {
}
}
frameInfo.image = image;
if (idx) {
QImage pimg(canvasSize, QImage::Format_RGBA8888);
QPainter p(&pimg);
p.setRenderHint(QPainter::RenderHint::HighQualityAntialiasing);
pimg.fill(Qt::transparent);
p.drawImage(QPoint(), lastimg);
p.drawImage(QPoint(left, top), image);
lastimg.swap(pimg);
} else {
lastimg.swap(image);
}
frameInfo.image = lastimg;
frameInfos.append(frameInfo);
}
@ -251,7 +268,9 @@ bool QGifImagePrivate::save(QIODevice *device,
}
gifFile->ImageCount = frameInfos.size();
gifFile->SavedImages = new SavedImage[ulong(frameInfos.size())];
gifFile->SavedImages =
(SavedImage *)calloc((size_t)frameInfos.size(), sizeof(SavedImage));
for (int idx = 0; idx < frameInfos.size(); ++idx) {
const QGifFrameInfoData frameInfo = frameInfos.at(idx);
QImage image = frameInfo.image;
@ -265,8 +284,8 @@ bool QGifImagePrivate::save(QIODevice *device,
SavedImage *gifImage = gifFile->SavedImages + idx;
gifImage->ImageDesc.Left = frameInfo.offset.x();
gifImage->ImageDesc.Top = frameInfo.offset.y();
gifImage->ImageDesc.Left = 0;
gifImage->ImageDesc.Top = 0;
gifImage->ImageDesc.Width = image.width();
gifImage->ImageDesc.Height = image.height();
gifImage->ImageDesc.Interlace = frameInfo.interlace;
@ -458,7 +477,7 @@ void QGifImage::insertFrame(int index, const QImage &frame, int delay) {
QGifFrameInfoData data;
data.image = frame;
data.delayTime = delay;
data.offset = frame.offset();
// data.offset = frame.offset();
d->frameInfos.insert(index, data);
}
@ -473,16 +492,16 @@ void QGifImage::insertFrame(int index, const QImage &frame, int delay) {
converted to the QImage::Format_Indexed8 format. Global color table will be
used in the convertion if it has been set.
*/
void QGifImage::insertFrame(int index, const QImage &frame,
const QPoint &offset, int delay) {
Q_D(QGifImage);
QGifFrameInfoData data;
data.image = frame;
data.delayTime = delay;
data.offset = offset;
// void QGifImage::insertFrame(int index, const QImage &frame,
// const QPoint &offset, int delay) {
// Q_D(QGifImage);
// QGifFrameInfoData data;
// data.image = frame;
// data.delayTime = delay;
// data.offset = offset;
d->frameInfos.insert(index, data);
}
// d->frameInfos.insert(index, data);
//}
/*!
Append the QImage object \a frame with \a delay.
@ -499,25 +518,26 @@ void QGifImage::addFrame(const QImage &frame, int delay) {
QGifFrameInfoData data;
data.image = frame;
data.delayTime = delay;
data.offset = frame.offset();
// data.offset = frame.offset();
d->frameInfos.append(data);
}
/*!
\overload
Append the QImage object \a frame with the given \a offset and \a delay.
Append the QImage object \a frame with the given \a delay.
*/
void QGifImage::addFrame(const QImage &frame, const QPoint &offset, int delay) {
Q_D(QGifImage);
// void QGifImage::addFrame(const QImage &frame, const QPoint &offset, int
// delay) {
// Q_D(QGifImage);
QGifFrameInfoData data;
data.image = frame;
data.delayTime = delay;
data.offset = offset;
// QGifFrameInfoData data;
// data.image = frame;
// data.delayTime = delay;
// //data.offset = offset;
d->frameInfos.append(data);
}
// d->frameInfos.append(data);
//}
/*!
Return frame count contained in the gif file.
@ -541,23 +561,23 @@ QImage QGifImage::frame(int index) const {
/*!
Return the offset value of the frame at \a index
*/
QPoint QGifImage::frameOffset(int index) const {
Q_D(const QGifImage);
if (index < 0 || index >= d->frameInfos.size())
return QPoint();
// QPoint QGifImage::frameOffset(int index) const {
// Q_D(const QGifImage);
// if (index < 0 || index >= d->frameInfos.size())
// return QPoint();
return d->frameInfos[index].offset;
}
// return d->frameInfos[index].offset;
//}
/*!
Set the \a offset value for the frame at \a index
*/
void QGifImage::setFrameOffset(int index, const QPoint &offset) {
Q_D(QGifImage);
if (index < 0 || index >= d->frameInfos.size())
return;
d->frameInfos[index].offset = offset;
}
// void QGifImage::setFrameOffset(int index, const QPoint &offset) {
// Q_D(QGifImage);
// if (index < 0 || index >= d->frameInfos.size())
// return;
// d->frameInfos[index].offset = offset;
// }
/*!
Return the delay value of the frame at \a index
@ -593,10 +613,11 @@ QColor QGifImage::frameTransparentColor(int index) const {
/*!
Sets the transparent \a color of the frame \a index. Unlike other image
formats that support alpha (e.g. PNG), GIF does not support semi-transparent
pixels. The way to achieve transparency is to set a color that will be
transparent when rendering the GIF. So, if you set the transparent color to
black, the black pixels in your gif file will be transparent.
formats that support alpha (e.g. PNG), GIF does not support
semi-transparent pixels. The way to achieve transparency is to set a color
that will be transparent when rendering the GIF. So, if you set the
transparent color to black, the black pixels in your gif file will be
transparent.
*/
void QGifImage::setFrameTransparentColor(int index, const QColor &color) {
Q_D(QGifImage);
@ -627,6 +648,8 @@ int QGifImage::getLastError() { return _lasterr; }
void QGifImage::removeFrame(int index) {
Q_D(QGifImage);
if (index < 0 || index >= d->frameInfos.size())
return;
d->frameInfos.removeAt(index);
}
@ -643,7 +666,7 @@ void QGifImage::flip(FlipDirection dir) {
auto &img = item.image;
switch (dir) {
case FlipDirection::Horizontal:
img = img.mirrored();
img = img.mirrored(true, false);
break;
case FlipDirection::Vertical:
img = img.mirrored(false, true);
@ -656,13 +679,58 @@ void QGifImage::rotate(bool clockwise) {
Q_D(QGifImage);
d->canvasSize = d->canvasSize.transposed();
QTransform trans;
trans.rotate(clockwise ? 90.0 : -90.0);
trans.rotate(clockwise ? -90.0 : 90.0);
for (auto &item : d->frameInfos) {
auto &img = item.image;
img = img.transformed(trans);
}
}
int QGifImage::width() {
Q_D(const QGifImage);
return d->canvasSize.width();
}
int QGifImage::height() {
Q_D(const QGifImage);
return d->canvasSize.height();
}
QSize QGifImage::size() {
Q_D(const QGifImage);
return d->canvasSize;
}
QPixmap QGifImage::frameimg(int index) const {
return QPixmap::fromImage(frame(index));
}
bool QGifImage::moveleft(int index) {
Q_D(QGifImage);
if (index < 1 || index >= d->frameInfos.size())
return false;
d->frameInfos.move(index, index - 1);
return true;
}
bool QGifImage::moveright(int index) {
Q_D(QGifImage);
if (index < 0 || index >= d->frameInfos.size() - 1)
return false;
d->frameInfos.move(index, index + 1);
return true;
}
void QGifImage::createReverse(int from, int to) {
Q_D(QGifImage);
auto &l = d->frameInfos;
if (from < 0 || from >= l.size() - 1)
return;
if (to < 0 || to >= l.size() - 1)
return;
std::reverse_copy(l.begin() + from, l.begin() + to, l.begin() + to);
}
/*!
\overload
@ -677,9 +745,9 @@ bool QGifImage::save(QIODevice *device) const {
}
/*!
Loads an gif image from the file with the given \a fileName. Returns \c true
if the image was successfully loaded; otherwise invalidates the image and
returns \c false.
Loads an gif image from the file with the given \a fileName. Returns \c
true if the image was successfully loaded; otherwise invalidates the image
and returns \c false.
*/
bool QGifImage::load(const QString &fileName) {
Q_D(QGifImage);

View File

@ -58,13 +58,13 @@ public:
QImage frame(int index) const;
void addFrame(const QImage &frame, int delay = -1);
void addFrame(const QImage &frame, const QPoint &offset, int delay = -1);
// void addFrame(const QImage &frame, const QPoint &offset, int delay = -1);
void insertFrame(int index, const QImage &frame, int delay = -1);
void insertFrame(int index, const QImage &frame, const QPoint &offset,
int delay = -1);
// void insertFrame(int index, const QImage &frame, const QPoint &offset,
// int delay = -1);
QPoint frameOffset(int index) const;
void setFrameOffset(int index, const QPoint &offset);
// QPoint frameOffset(int index) const;
// void setFrameOffset(int index, const QPoint &offset);
int frameDelay(int index) const;
void setFrameDelay(int index, int delay);
QColor frameTransparentColor(int index) const;
@ -85,6 +85,13 @@ public:
void reverse(); //反转帧
void flip(FlipDirection dir); //反转帧图像
void rotate(bool clockwise = true); //旋转90度图像默认为顺时针
int width();
int height();
QSize size();
QPixmap frameimg(int index) const;
bool moveleft(int index);
bool moveright(int index);
void createReverse(int from, int to);
private:
int _lasterr;

View File

@ -30,14 +30,15 @@
#include "gif_lib.h"
#include <QColor>
#include <QPixmap>
#include <QVector>
class QGifFrameInfoData {
public:
QGifFrameInfoData() : delayTime(-1), interlace(false) {}
QImage image;
QPoint offset; // offset info of QImage will lost when convert from One format
// to another.
// QPoint offset;
// offset info of QImage will lost when convert from One format to another.
int delayTime;
bool interlace;
QColor transparentColor;

View File

@ -10,9 +10,15 @@ TEMPLATE = app
SOURCES += \
main.cpp \
mainwindow.cpp \
gifeditorscene.cpp
sponsordialog.cpp \
newdialog.cpp \
exportdialog.cpp \
createreversedialog.cpp
RESOURCES += resources.qrc
HEADERS += mainwindow.h \
gifeditorscene.h
sponsordialog.h \
newdialog.h \
exportdialog.h \
createreversedialog.h

6
createreversedialog.cpp Normal file
View File

@ -0,0 +1,6 @@
#include "createreversedialog.h"
CreateReverseDialog::CreateReverseDialog()
{
}

11
createreversedialog.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef CREATEREVERSEDIALOG_H
#define CREATEREVERSEDIALOG_H
class CreateReverseDialog
{
public:
CreateReverseDialog();
};
#endif // CREATEREVERSEDIALOG_H

6
exportdialog.cpp Normal file
View File

@ -0,0 +1,6 @@
#include "exportdialog.h"
ExportDialog::ExportDialog()
{
}

11
exportdialog.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef EXPORTDIALOG_H
#define EXPORTDIALOG_H
class ExportDialog
{
public:
ExportDialog();
};
#endif // EXPORTDIALOG_H

View File

@ -1,18 +0,0 @@
#include "gifeditorscene.h"
#include <QGraphicsView>
GifEditorScene::GifEditorScene(QObject *parent) : QGraphicsScene(parent) {}
void GifEditorScene::setBackgroundImage(QImage img) {
m_back = QPixmap::fromImage(img);
}
void GifEditorScene::drawBackground(QPainter *painter, const QRectF &rect) {
Q_UNUSED(rect)
if (views().count() == 0)
return;
QGraphicsView *pView = views().first();
QRect contentRect = pView->viewport()->contentsRect();
QRectF sceneRect = pView->mapToScene(contentRect).boundingRect();
painter->drawPixmap(sceneRect, m_back, QRect());
}

View File

@ -1,19 +0,0 @@
#ifndef GIFEDITOR_H
#define GIFEDITOR_H
#include <QGraphicsScene>
class GifEditorScene : public QGraphicsScene {
Q_OBJECT
public:
GifEditorScene(QObject *parent = nullptr);
void setBackgroundImage(QImage img);
protected:
void drawBackground(QPainter *painter, const QRectF &rect) override;
QPixmap m_back;
};
#endif // GIFEDITOR_H

BIN
images/blank.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

BIN
images/cutpic.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
images/export.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

BIN
images/fliph.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
images/flipv.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
images/model.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

BIN
images/reverseplus.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
images/rotatel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

BIN
images/rotater.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
images/scale.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@ -1,10 +1,14 @@
#include "mainwindow.h"
#include "sponsordialog.h"
#include <DInputDialog>
#include <DMenu>
#include <DMessageManager>
#include <DTitlebar>
#include <DToolBar>
#include <DToolButton>
#include <QFileDialog>
#include <QListWidgetItem>
#include <QMessageBox>
#include <QShortcut>
#include <QVBoxLayout>
#include <QWidget>
@ -12,7 +16,7 @@
#define ICONRES(name) QIcon(":/images/" name ".png")
MainWindow::MainWindow(DMainWindow *parent) : DMainWindow(parent) {
setMinimumSize(600, 500);
setMinimumSize(800, 600);
setWindowTitle(tr("WingGifEditor"));
setWindowIcon(ICONRES("icon"));
auto w = new QWidget(this);
@ -34,7 +38,7 @@ MainWindow::MainWindow(DMainWindow *parent) : DMainWindow(parent) {
connect(imglist, &QListWidget::itemSelectionChanged, this, [=] {
auto scene = new QGraphicsScene(editor);
scene->addPixmap(QPixmap::fromImage(gif.frame(imglist->currentRow())));
scene->addPixmap(gif.frameimg(imglist->currentRow()));
editor->setScene(scene);
});
@ -72,6 +76,11 @@ MainWindow::MainWindow(DMainWindow *parent) : DMainWindow(parent) {
auto keyscaledelay =
QKeySequence(Qt::KeyboardModifier::ControlModifier |
Qt::KeyboardModifier::ShiftModifier | Qt::Key_T);
auto keyscalepic =
QKeySequence(Qt::KeyboardModifier::ShiftModifier | Qt::Key_T);
auto keycutpic =
QKeySequence(Qt::KeyboardModifier::ControlModifier |
Qt::KeyboardModifier::ShiftModifier | Qt::Key_X);
#define AddMenuIconAction(Icon, Title, Slot, Owner) \
a = new QAction(Owner); \
@ -111,6 +120,7 @@ MainWindow::MainWindow(DMainWindow *parent) : DMainWindow(parent) {
QKeySequence::Save);
AddMenuShortcutAction("saveas", tr("SaveAs"), MainWindow::on_saveas, tm,
QKeySequence::SaveAs);
AddMenuIconAction("export", tr("Export"), MainWindow::on_export, tm);
tm->addSeparator();
AddMenuShortcutAction("close", tr("Close"), MainWindow::on_exit, tm,
QKeySequence::Close);
@ -156,7 +166,7 @@ MainWindow::MainWindow(DMainWindow *parent) : DMainWindow(parent) {
AddMenuShortcutAction("pause", tr("Stop"), MainWindow::on_stop, tm, keypause);
AddMenuShortcutAction("foreword", tr("NextFrame"), MainWindow::on_next, tm,
keynextframe);
AddMenuShortcutAction("last", tr("EndFrame"), MainWindow::on_last, tm,
AddMenuShortcutAction("last", tr("EndFrame"), MainWindow::on_endframe, tm,
keylastframe);
title->setMenu(menu);
@ -176,12 +186,38 @@ MainWindow::MainWindow(DMainWindow *parent) : DMainWindow(parent) {
keymvr);
AddMenuShortcutAction("reverse", tr("Reverse"), MainWindow::on_reverse, tm,
keyrev);
AddMenuAction(tr("CreateReverse"), MainWindow::on_createreverse, tm);
AddMenuIconAction("reverseplus", tr("CreateReverse"),
MainWindow::on_createreverse, tm);
tm->addSeparator();
AddMenuShortcutAction("setdelay", tr("SetDelay"), MainWindow::on_setdelay, tm,
keysetdelay);
AddMenuShortcutAction("scaledelay", tr("ScaleDelay"),
MainWindow::on_scaledelay, tm, keyscaledelay);
AddMenuIconAction("pics", tr("InsertPics"), MainWindow::on_insertpic, tm);
AddMenuIconAction("gifs", tr("MergeGIfs"), MainWindow::on_merge, tm);
AddMenuShortcutAction("scale", tr("ScaleGif"), MainWindow::on_scalepic, tm,
keyscalepic);
AddMenuShortcutAction("cutpic", tr("CutGif"), MainWindow::on_cutpic, tm,
keycutpic);
tm->addSeparator();
AddMenuIconAction("fliph", tr("FilpH"), MainWindow::on_fliph, tm);
AddMenuIconAction("flipv", tr("FlipV"), MainWindow::on_flipv, tm);
AddMenuIconAction("rotatel", tr("RotateLeft"), MainWindow::on_clockwise, tm);
AddMenuIconAction("rotater", tr("RotateR"), MainWindow::on_anticlockwise, tm);
tm->addSeparator();
AddMenuIconAction("blank", tr("ExportBlank"), MainWindow::on_exportapply, tm);
AddMenuIconAction("model", tr("ApplyModel"), MainWindow::on_applypic, tm);
menu->addMenu(tm);
tm = new DMenu(this);
tm->setTitle(tr("Author"));
tm->setIcon(ICONRES("author"));
AddMenuIconAction("soft", tr("About"), MainWindow::on_about, tm);
AddMenuIconAction("sponsor", tr("Sponsor"), MainWindow::on_sponsor, tm);
AddMenuIconAction("wiki", tr("Wiki"), MainWindow::on_wiki, tm);
a = new QAction(ICONRES("qt"), tr("AboutQT"), tm);
connect(a, &QAction::triggered, this, [=] { QMessageBox::aboutQt(this); });
tm->addAction(a);
menu->addMenu(tm);
auto toolbar = new DToolBar(this);
@ -196,10 +232,89 @@ MainWindow::MainWindow(DMainWindow *parent) : DMainWindow(parent) {
#define AddToolBarTool(Icon, Slot, ToolTip) \
AddToolBarAction(Icon, toolbar, Slot, ToolTip)
DToolButton *tbtn;
DMenu *tmenu;
#define AddToolBtnBegin(DIcon) \
tbtn = new DToolButton(this); \
tbtn->setIcon(ICONRES(DIcon)); \
tmenu = new DMenu(this);
#define AddToolBtnBtn(Icon, Title, Slot) \
a = new QAction(ICONRES(Icon), Title, this); \
connect(a, &QAction::triggered, this, &Slot); \
tmenu->addAction(a);
#define AddToolBtnEnd() \
tbtn->setMenu(tmenu); \
tbtn->setPopupMode(DToolButton::ToolButtonPopupMode::InstantPopup); \
toolbar->addWidget(tbtn);
AddToolBtnBegin("new") {
AddToolBtnBtn("pics", tr("NewFromPics"), MainWindow::on_new_frompics);
AddToolBtnBtn("gifs", tr("NewFromGifs"), MainWindow::on_new_fromgifs);
}
AddToolBtnEnd();
AddToolBarTool("open", MainWindow::on_open, tr("Open"));
AddToolBarTool("save", MainWindow::on_save, tr("Save"));
AddToolBarTool("saveas", MainWindow::on_saveas, tr("SaveAs"));
AddToolBarTool("del", MainWindow::on_del, tr("Del"));
AddToolBarTool("export", MainWindow::on_export, tr("Export"));
toolbar->addSeparator();
AddToolBarTool("undo", MainWindow::on_undo, tr("Undo"));
AddToolBarTool("redo", MainWindow::on_redo, tr("Redo"));
AddToolBarTool("cut", MainWindow::on_cut, tr("Cut"));
AddToolBarTool("copy", MainWindow::on_copy, tr("Copy"));
AddToolBarTool("paste", MainWindow::on_paste, tr("Paste"));
AddToolBarTool("del", MainWindow::on_del, tr("Delete"));
AddToolBarTool("selall", MainWindow::on_selall, tr("SelectAll"));
AddToolBarTool("desel", MainWindow::on_desel, tr("Deselect"));
AddToolBarTool("selrev", MainWindow::on_selreverse, tr("ReverseSelection"));
AddToolBarTool("jmp", MainWindow::on_goto, tr("Goto"));
toolbar->addSeparator();
AddToolBarTool("soft", MainWindow::on_about, tr("About"));
AddToolBarTool("sponsor", MainWindow::on_sponsor, tr("Sponsor"));
AddToolBarTool("wiki", MainWindow::on_wiki, tr("Wiki"));
toolbar->setObjectName("main");
addToolBar(toolbar);
addToolBarBreak();
toolbar = new DToolBar(this);
AddToolBarTool("rmframe", MainWindow::on_decreaseframe, tr("ReduceFrame"));
AddToolBarTool("rml", MainWindow::on_delbefore, tr("DeleteBefore"));
AddToolBarTool("rmr", MainWindow::on_delafter, tr("DeleteAfter"));
AddToolBarTool("mvf", MainWindow::on_moveleft, tr("MoveLeft"));
AddToolBarTool("mvb", MainWindow::on_moveright, tr("MoveRight"));
AddToolBarTool("reverse", MainWindow::on_reverse, tr("Reverse"));
AddToolBarTool("reverseplus", MainWindow::on_createreverse,
tr("CreateReverse"));
toolbar->addSeparator();
AddToolBarTool("setdelay", MainWindow::on_setdelay, tr("SetDelay"));
AddToolBarTool("scaledelay", MainWindow::on_scaledelay, tr("ScaleDelay"));
AddToolBarTool("pics", MainWindow::on_insertpic, tr("InsertPics"));
AddToolBarTool("gifs", MainWindow::on_merge, tr("MergeGIfs"));
AddToolBarTool("scale", MainWindow::on_scalepic, tr("ScaleGif"));
AddToolBarTool("cutpic", MainWindow::on_cutpic, tr("CutGif"));
toolbar->addSeparator();
AddToolBarTool("fliph", MainWindow::on_fliph, tr("FilpH"));
AddToolBarTool("flipv", MainWindow::on_flipv, tr("FlipV"));
AddToolBarTool("rotatel", MainWindow::on_clockwise, tr("RotateLeft"));
AddToolBarTool("rotater", MainWindow::on_anticlockwise, tr("RotateR"));
toolbar->addSeparator();
AddToolBarTool("blank", MainWindow::on_exportapply, tr("ExportBlank"));
AddToolBarTool("model", MainWindow::on_applypic, tr("ApplyModel"));
toolbar->setObjectName("pic");
addToolBar(toolbar);
toolbar = new DToolBar(this);
AddToolBarTool("first", MainWindow::on_beginframe, tr("FirstFrame"));
AddToolBarTool("back", MainWindow::on_last, tr("LastFrame"));
AddToolBarTool("gifplay", MainWindow::on_play, tr("Play"));
AddToolBarTool("pause", MainWindow::on_stop, tr("Stop"));
AddToolBarTool("foreword", MainWindow::on_next, tr("NextFrame"));
AddToolBarTool("last", MainWindow::on_endframe, tr("EndFrame"));
toolbar->setObjectName("play");
addToolBar(toolbar);
status = new DStatusBar(this);
@ -209,7 +324,7 @@ MainWindow::MainWindow(DMainWindow *parent) : DMainWindow(parent) {
void MainWindow::refreshImglist() {
imglist->clear();
for (int i = 0; i < gif.frameCount(); i++) {
new QListWidgetItem(QIcon(QPixmap::fromImage(gif.frame(i))),
new QListWidgetItem(QIcon(gif.frameimg(i)),
QString("%1 %2 ms").arg(i).arg(gif.frameDelay(i)),
imglist);
}
@ -303,7 +418,8 @@ void MainWindow::on_del() {
std::sort(indices.begin(), indices.end());
int offset = 0;
for (auto item : indices) {
gif.removeFrame(item - offset);
auto off = item - offset;
gif.removeFrame(off);
offset++;
}
for (auto item : imglist->selectedItems()) {
@ -331,7 +447,15 @@ void MainWindow::on_desel() {
imglist->setCurrentRow(cur);
}
void MainWindow::on_goto() {}
void MainWindow::on_goto() {
bool ok;
auto index =
DInputDialog::getInt(this, tr("Goto"), tr("PleaseInputIndex"),
imglist->currentRow(), 0, imglist->count(), 1, &ok);
if (ok) {
imglist->setCurrentRow(index);
}
}
void MainWindow::on_beginframe() { imglist->setCurrentRow(0); }
@ -361,10 +485,15 @@ void MainWindow::on_decreaseframe() {}
void MainWindow::on_delbefore() {
auto len = imglist->currentRow();
for (auto i = 0; i < len; i++) {
gif.removeFrame(0);
auto del = imglist->item(i);
auto del = imglist->item(0);
imglist->removeItemWidget(del);
delete del;
gif.removeFrame(0);
}
len = imglist->count();
for (auto i = 0; i < len; i++) {
imglist->item(i)->setText(
QString("%1 %2 ms").arg(i).arg(gif.frameDelay(i)));
}
}
@ -372,10 +501,10 @@ void MainWindow::on_delafter() {
auto len = imglist->count() - imglist->currentRow() - 1;
auto pos = imglist->currentRow() + 1;
for (auto i = 0; i < len; i++) {
gif.removeFrame(pos);
auto del = imglist->item(pos);
imglist->removeItemWidget(del);
delete del;
gif.removeFrame(pos);
}
}
@ -394,6 +523,8 @@ void MainWindow::on_saveas() {
}
}
void MainWindow::on_export() {}
void MainWindow::on_exit() { close(); }
void MainWindow::on_undo() {}
@ -426,9 +557,33 @@ void MainWindow::on_reverse() {
refreshImglist();
}
void MainWindow::on_moveleft() {}
void MainWindow::on_moveleft() {
auto pos = imglist->currentRow();
if (gif.moveleft(pos)) {
auto p = imglist->item(pos);
p->setIcon(QIcon(gif.frameimg(pos)));
p->setText(QString("%1 %2 ms").arg(pos).arg(gif.frameDelay(pos)));
pos--;
p = imglist->item(pos);
p->setIcon(QIcon(gif.frameimg(pos)));
p->setText(QString("%1 %2 ms").arg(pos).arg(gif.frameDelay(pos)));
imglist->setCurrentRow(pos);
}
}
void MainWindow::on_moveright() {}
void MainWindow::on_moveright() {
auto pos = imglist->currentRow();
if (gif.moveright(pos)) {
auto p = imglist->item(pos);
p->setIcon(QIcon(gif.frameimg(pos)));
p->setText(QString("%1 %2 ms").arg(pos).arg(gif.frameDelay(pos)));
pos++;
p = imglist->item(pos);
p->setIcon(QIcon(gif.frameimg(pos)));
p->setText(QString("%1 %2 ms").arg(pos).arg(gif.frameDelay(pos)));
imglist->setCurrentRow(pos);
}
}
void MainWindow::on_createreverse() {}
@ -445,27 +600,42 @@ void MainWindow::on_scalepic() {}
void MainWindow::on_cutpic() {}
void MainWindow::on_fliph() {
auto pos = imglist->currentRow();
gif.flip(FlipDirection::Horizontal);
refreshImglist();
imglist->setCurrentRow(pos);
}
void MainWindow::on_flipv() {
auto pos = imglist->currentRow();
gif.flip(FlipDirection::Vertical);
refreshImglist();
imglist->setCurrentRow(pos);
}
void MainWindow::on_clockwise() {
auto pos = imglist->currentRow();
gif.rotate();
refreshImglist();
imglist->setCurrentRow(pos);
}
void MainWindow::on_anticlockwise() {
auto pos = imglist->currentRow();
gif.rotate(false);
refreshImglist();
imglist->setCurrentRow(pos);
}
void MainWindow::on_exportapply() {}
void MainWindow::on_applypic() {}
void MainWindow::on_about() {}
void MainWindow::on_sponsor() {}
void MainWindow::on_sponsor() {
SponsorDialog d;
d.exec();
}
void MainWindow::on_wiki() {}

View File

@ -2,7 +2,6 @@
#define MAINWINDOW_H
#include "QtGifImage/gifimage/qgifimage.h"
#include "gifeditorscene.h"
#include <DGraphicsView>
#include <DLabel>
#include <DMainWindow>
@ -52,6 +51,7 @@ private:
void on_open();
void on_save();
void on_saveas();
void on_export();
void on_exit();
void on_undo();
@ -90,6 +90,7 @@ private:
void on_flipv();
void on_clockwise();
void on_anticlockwise();
void on_exportapply();
void on_applypic();
void on_about();

6
newdialog.cpp Normal file
View File

@ -0,0 +1,6 @@
#include "newdialog.h"
NewDialog::NewDialog()
{
}

11
newdialog.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef NEWDIALOG_H
#define NEWDIALOG_H
class NewDialog
{
public:
NewDialog();
};
#endif // NEWDIALOG_H

View File

@ -45,5 +45,16 @@
<file>images/setdelay.png</file>
<file>images/scaledelay.png</file>
<file>images/icon.png</file>
<file>sponsor.png</file>
<file>images/export.png</file>
<file>images/scale.png</file>
<file>images/cutpic.png</file>
<file>images/fliph.png</file>
<file>images/flipv.png</file>
<file>images/rotatel.png</file>
<file>images/rotater.png</file>
<file>images/reverseplus.png</file>
<file>images/blank.png</file>
<file>images/model.png</file>
</qresource>
</RCC>

BIN
sponsor.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 776 KiB

17
sponsordialog.cpp Normal file
View File

@ -0,0 +1,17 @@
#include "sponsordialog.h"
#include <DLabel>
#include <QPixmap>
SponsorDialog::SponsorDialog(DMainWindow *parent) : DDialog(parent) {
setWindowTitle(tr("Sponsor"));
addSpacing(5);
addContent(new DLabel(tr("ThanksForSponsor"), this), Qt::AlignHCenter);
addSpacing(5);
QPixmap sponsor(":/sponsor.png");
auto l = new DLabel(this);
l->setPixmap(sponsor);
l->setScaledContents(true);
addContent(l);
}

19
sponsordialog.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef SPONSORDIALOG_H
#define SPONSORDIALOG_H
#include <DDialog>
#include <DMainWindow>
#include <QObject>
DWIDGET_USE_NAMESPACE
class SponsorDialog : public DDialog {
Q_OBJECT
public:
explicit SponsorDialog(DMainWindow *parent = nullptr);
signals:
public slots:
};
#endif // SPONSORDIALOG_H