update
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
#include "createreversedialog.h"
|
||||
|
||||
CreateReverseDialog::CreateReverseDialog()
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef CREATEREVERSEDIALOG_H
|
||||
#define CREATEREVERSEDIALOG_H
|
||||
|
||||
|
||||
class CreateReverseDialog
|
||||
{
|
||||
public:
|
||||
CreateReverseDialog();
|
||||
};
|
||||
|
||||
#endif // CREATEREVERSEDIALOG_H
|
|
@ -0,0 +1,6 @@
|
|||
#include "exportdialog.h"
|
||||
|
||||
ExportDialog::ExportDialog()
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef EXPORTDIALOG_H
|
||||
#define EXPORTDIALOG_H
|
||||
|
||||
|
||||
class ExportDialog
|
||||
{
|
||||
public:
|
||||
ExportDialog();
|
||||
};
|
||||
|
||||
#endif // EXPORTDIALOG_H
|
|
@ -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());
|
||||
}
|
|
@ -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
|
After Width: | Height: | Size: 6.5 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 6.9 KiB |
After Width: | Height: | Size: 4.7 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 6.4 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 4.9 KiB |
198
mainwindow.cpp
|
@ -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() {}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
#include "newdialog.h"
|
||||
|
||||
NewDialog::NewDialog()
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef NEWDIALOG_H
|
||||
#define NEWDIALOG_H
|
||||
|
||||
|
||||
class NewDialog
|
||||
{
|
||||
public:
|
||||
NewDialog();
|
||||
};
|
||||
|
||||
#endif // NEWDIALOG_H
|
|
@ -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>
|
||||
|
|
After Width: | Height: | Size: 776 KiB |
|
@ -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);
|
||||
}
|
|
@ -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
|