This commit is contained in:
寂静的羽夏 2022-08-14 18:14:04 +08:00
parent b9b62bb786
commit d370e4ffdc
7 changed files with 163 additions and 53 deletions

View File

@ -625,7 +625,7 @@ void MainWindow::openGif(QString filename) {
setEditMode(false); setEditMode(false);
DMessageManager::instance()->sendMessage(this, ICONRES("icon"), DMessageManager::instance()->sendMessage(this, ICONRES("icon"),
"OpenError"); "OpenError");
QMessageBox::critical(this, "", QMessageBox::critical(this, tr("OpenError"),
QString(GifErrorString(gif.getLastError()))); QString(GifErrorString(gif.getLastError())));
return; return;
} }
@ -1035,6 +1035,7 @@ void MainWindow::on_exit() {
iReadWrite->setPixmap(inforwg); iReadWrite->setPixmap(inforwg);
status->showMessage(""); status->showMessage("");
curfilename.clear(); curfilename.clear();
undo.clear();
} }
} }
@ -1329,5 +1330,6 @@ void MainWindow::dropEvent(QDropEvent *event) {
const QMimeData *mimeData = event->mimeData(); const QMimeData *mimeData = event->mimeData();
if (mimeData->hasUrls()) { if (mimeData->hasUrls()) {
auto filename = mimeData->urls().first().toLocalFile(); auto filename = mimeData->urls().first().toLocalFile();
openGif(filename);
} }
} }

View File

@ -322,6 +322,7 @@ bool GifDecoder::exportImages(QString folder, QString ext) {
void GifDecoder::close() { void GifDecoder::close() {
frameInfos.clear(); frameInfos.clear();
canvasSize = QSize(); canvasSize = QSize();
emit frameRefreshAll();
} }
void GifDecoder::setOnionIndex(int index) { void GifDecoder::setOnionIndex(int index) {
@ -363,6 +364,7 @@ void GifDecoder::setFrameDelay(int index, int delay) {
if (index < 0 || index >= frameInfos.count()) if (index < 0 || index >= frameInfos.count())
return; return;
frameInfos[index].delayTime = delay; frameInfos[index].delayTime = delay;
emit frameDelaySet(index, delay);
} }
void GifDecoder::setAllFrameDelay(int delay) { void GifDecoder::setAllFrameDelay(int delay) {
@ -420,6 +422,7 @@ void GifDecoder::scale(int w, int h) {
auto &img = frame.image; auto &img = frame.image;
img = img.scaled(w, h); img = img.scaled(w, h);
} }
emit frameImageChanged();
} }
QVector<QRgb> QVector<QRgb>

View File

@ -19,23 +19,17 @@
&emsp;&emsp;有关本软件提建议的时候不要天马行空,本软件的定位是提供简单易用满足基本需求的 GIF 编辑器,并不是像`ScreenToGif`,一是没有相关基础知识,自己一个人搞不动;二是没必要,我不想把这个软件搞个大而全,配合`Gimp`等优秀的图像编辑器作为辅助,来编辑 GIF 图像绰绰有余了。 &emsp;&emsp;有关本软件提建议的时候不要天马行空,本软件的定位是提供简单易用满足基本需求的 GIF 编辑器,并不是像`ScreenToGif`,一是没有相关基础知识,自己一个人搞不动;二是没必要,我不想把这个软件搞个大而全,配合`Gimp`等优秀的图像编辑器作为辅助,来编辑 GIF 图像绰绰有余了。
### 软件依赖 ### GIF 库
&emsp;&emsp;本软件基于`ImageMagick`,它是一个强大的图片处理库,这个是官网介绍: &emsp;&emsp;本软件基于两个库修改定制而得,一个负责读:`QtGifImage`,另一个负责写:`BurstLinker`。
> Use ImageMagick® to create, edit, compose, or convert digital images. It can read and write images in a variety of formats (over 200) including PNG, JPEG, GIF, WebP, HEIC, SVG, PDF, DPX, EXR and TIFF. ImageMagick can resize, flip, mirror, rotate, distort, shear and transform images, adjust image colors, apply various special effects, or draw text, lines, polygons, ellipses and Bézier curves. &emsp;&emsp;`BurstLinker`是`Android`平台上一个`GIF`编码库,还不错。它的底层实现是`C++`,所以我可以进行略微的修改定制得到,仓库 [链接](https://github.com/yutianzuo/BurstLinker) 。
&emsp;&emsp;功能挺强大的,似乎对于该软件有点大材小用,不过我会尽量充分利用该库,实现与 GIF 编辑相关的操作 &emsp;&emsp;`QtGifImage`是`Qt`上的`GIF`读写库,可以将`GIF`解析为`QImage`序列,基于`giflib`。这个我改动比较大,只保留了读取部分,并与我的软件做了适配(这个库写`GIF`图片的质量有点太差),仓库 [链接](https://github.com/jiangcaiyang/QtGifImage)
### 编译安装 ### 编译安装
&emsp;&emsp;由于本软件依赖`ImageMagick`和`DTK``DTK`直接在深度应用商店下载就行了,前者你需要在终端输入: &emsp;&emsp;由于本软件依赖`Qt`和`DTK``DTK`直接在深度应用商店下载就行了。安装完毕后,打开项目,你就可以直接编译该软件了。
```bash
sudo apt install graphicsmagick-libmagick-dev-compat
```
&emsp;&emsp;安装完毕后,打开项目,你就可以直接编译该软件了。
### 参与贡献 ### 参与贡献
@ -63,6 +57,10 @@ sudo apt install graphicsmagick-libmagick-dev-compat
<p align="center">羽云 GIF 编辑器</p> <p align="center">羽云 GIF 编辑器</p>
</p> </p>
## TODO
&emsp;&emsp;本软件保存生成的 GIF 会比原来的大很多,这个是由于原理导致的。本想通过保留每个帧之间不同的部分实现减小体积,的确小了很多,比原文件稍大一点点,但是 GIF 播放有的部分会有白块,该实现代码已被注释掉,以备不时之需。
## 捐助 ## 捐助
**<p align="center">您的每一份支持都将是本项目推进的强大动力,十分感谢您的支持</p>** **<p align="center">您的每一份支持都将是本项目推进的强大动力,十分感谢您的支持</p>**

View File

@ -14,4 +14,5 @@ void CropImageCommand::undo() {
void CropImageCommand::redo() { void CropImageCommand::redo() {
gif->crop(rect.x(), rect.y(), rect.width(), rect.height()); gif->crop(rect.x(), rect.y(), rect.width(), rect.height());
gif->frameImageChanged();
} }

View File

@ -10,7 +10,9 @@ void ReplaceFrameCommand::undo() {
auto frames = gif->frames(); auto frames = gif->frames();
auto len = olds.count(); auto len = olds.count();
for (auto i = 0; i < len; i++) { for (auto i = 0; i < len; i++) {
frames[olds[i]].image.swap(bufferimage[i]); auto index = olds[i];
frames[index].image.swap(bufferimage[i]);
gif->frameRefreshImg(index);
} }
} }
@ -18,6 +20,8 @@ void ReplaceFrameCommand::redo() {
auto frames = gif->frames(); auto frames = gif->frames();
auto len = olds.count(); auto len = olds.count();
for (auto i = 0; i < len; i++) { for (auto i = 0; i < len; i++) {
frames[olds[i]].image.swap(bufferimage[i]); auto index = olds[i];
frames[index].image.swap(bufferimage[i]);
gif->frameRefreshImg(index);
} }
} }

Binary file not shown.

View File

@ -78,28 +78,121 @@
<translation></translation> <translation></translation>
</message> </message>
</context> </context>
<context>
<name>GifDecoder</name>
<message>
<location filename="../GifImage/decoder/gifdecoder.cpp" line="159"/>
<location filename="../GifImage/decoder/gifdecoder.cpp" line="189"/>
<source>Failed to open given file</source>
<translation></translation>
</message>
<message>
<location filename="../GifImage/decoder/gifdecoder.cpp" line="162"/>
<source>Failed to write to given file</source>
<translation></translation>
</message>
<message>
<location filename="../GifImage/decoder/gifdecoder.cpp" line="165"/>
<source>Screen descriptor has already been set</source>
<translation></translation>
</message>
<message>
<location filename="../GifImage/decoder/gifdecoder.cpp" line="168"/>
<source>Image descriptor is still active</source>
<translation></translation>
</message>
<message>
<location filename="../GifImage/decoder/gifdecoder.cpp" line="171"/>
<location filename="../GifImage/decoder/gifdecoder.cpp" line="204"/>
<source>Neither global nor local color map</source>
<translation></translation>
</message>
<message>
<location filename="../GifImage/decoder/gifdecoder.cpp" line="174"/>
<location filename="../GifImage/decoder/gifdecoder.cpp" line="210"/>
<source>Number of pixels bigger than width * height</source>
<translation></translation>
</message>
<message>
<location filename="../GifImage/decoder/gifdecoder.cpp" line="177"/>
<location filename="../GifImage/decoder/gifdecoder.cpp" line="213"/>
<source>Failed to allocate required memory</source>
<translation></translation>
</message>
<message>
<location filename="../GifImage/decoder/gifdecoder.cpp" line="180"/>
<source>Write failed (disk full?)</source>
<translation></translation>
</message>
<message>
<location filename="../GifImage/decoder/gifdecoder.cpp" line="183"/>
<location filename="../GifImage/decoder/gifdecoder.cpp" line="216"/>
<source>Failed to close given file</source>
<translation></translation>
</message>
<message>
<location filename="../GifImage/decoder/gifdecoder.cpp" line="186"/>
<source>Given file was not opened for write</source>
<translation></translation>
</message>
<message>
<location filename="../GifImage/decoder/gifdecoder.cpp" line="192"/>
<source>Failed to read from given file</source>
<translation></translation>
</message>
<message>
<location filename="../GifImage/decoder/gifdecoder.cpp" line="195"/>
<source>Data is not in GIF format</source>
<translation> GIF </translation>
</message>
<message>
<location filename="../GifImage/decoder/gifdecoder.cpp" line="198"/>
<source>No screen descriptor detected</source>
<translation></translation>
</message>
<message>
<location filename="../GifImage/decoder/gifdecoder.cpp" line="201"/>
<source>No Image Descriptor detected</source>
<translation></translation>
</message>
<message>
<location filename="../GifImage/decoder/gifdecoder.cpp" line="207"/>
<source>Wrong record type detected</source>
<translation></translation>
</message>
<message>
<location filename="../GifImage/decoder/gifdecoder.cpp" line="219"/>
<source>Given file was not opened for read</source>
<translation></translation>
</message>
<message>
<location filename="../GifImage/decoder/gifdecoder.cpp" line="222"/>
<source>Image is defective, decoding aborted</source>
<translation></translation>
</message>
<message>
<location filename="../GifImage/decoder/gifdecoder.cpp" line="225"/>
<source>Image EOF detected before image complete</source>
<translation></translation>
</message>
</context>
<context> <context>
<name>GifImage</name> <name>GifImage</name>
<message> <message>
<location filename="../GifImage/gifimage.cpp" line="36"/>
<location filename="../GifImage/gifimage.cpp" line="81"/>
<source>Unknown Error!</source> <source>Unknown Error!</source>
<translation></translation> <translation type="vanished"></translation>
</message> </message>
<message> <message>
<location filename="../GifImage/gifimage.cpp" line="92"/>
<source>UnSolvedBug</source> <source>UnSolvedBug</source>
<translation> Bug</translation> <translation type="vanished"> Bug</translation>
</message> </message>
<message> <message>
<location filename="../GifImage/gifimage.cpp" line="93"/>
<source>GIFUnSolveBugInfo</source> <source>GIFUnSolveBugInfo</source>
<translation> deconstructImages GIF 使 GIF </translation> <translation type="vanished"> deconstructImages GIF 使 GIF </translation>
</message> </message>
<message> <message>
<location filename="../GifImage/gifimage.cpp" line="363"/>
<source>Error</source> <source>Error</source>
<translation></translation> <translation type="vanished"></translation>
</message> </message>
</context> </context>
<context> <context>
@ -223,7 +316,7 @@
<message> <message>
<location filename="../Dialog/mainwindow.cpp" line="206"/> <location filename="../Dialog/mainwindow.cpp" line="206"/>
<location filename="../Dialog/mainwindow.cpp" line="376"/> <location filename="../Dialog/mainwindow.cpp" line="376"/>
<location filename="../Dialog/mainwindow.cpp" line="809"/> <location filename="../Dialog/mainwindow.cpp" line="891"/>
<source>Goto</source> <source>Goto</source>
<translation></translation> <translation></translation>
</message> </message>
@ -390,7 +483,7 @@
</message> </message>
<message> <message>
<location filename="../Dialog/mainwindow.cpp" line="293"/> <location filename="../Dialog/mainwindow.cpp" line="293"/>
<location filename="../Dialog/mainwindow.cpp" line="1180"/> <location filename="../Dialog/mainwindow.cpp" line="1289"/>
<source>OnionMask</source> <source>OnionMask</source>
<translation></translation> <translation></translation>
</message> </message>
@ -438,108 +531,117 @@
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../Dialog/mainwindow.cpp" line="679"/> <location filename="../Dialog/mainwindow.cpp" line="628"/>
<source>OpenError</source>
<translation></translation>
</message>
<message>
<location filename="../Dialog/mainwindow.cpp" line="687"/>
<source>ConfirmClose</source> <source>ConfirmClose</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../Dialog/mainwindow.cpp" line="680"/> <location filename="../Dialog/mainwindow.cpp" line="688"/>
<source>ConfirmSave</source> <source>ConfirmSave</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../Dialog/mainwindow.cpp" line="681"/> <location filename="../Dialog/mainwindow.cpp" line="689"/>
<source>Untitle</source> <source>Untitle</source>
<translation>.gif</translation> <translation>.gif</translation>
</message> </message>
<message> <message>
<location filename="../Dialog/mainwindow.cpp" line="698"/> <location filename="../Dialog/mainwindow.cpp" line="706"/>
<source>%1 frame | %2 total</source> <source>%1 frame | %2 total</source>
<translation> %1 | %2 </translation> <translation> %1 | %2 </translation>
</message> </message>
<message> <message>
<location filename="../Dialog/mainwindow.cpp" line="719"/> <location filename="../Dialog/mainwindow.cpp" line="727"/>
<source>PleaseWait!</source> <source>PleaseWait!</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../Dialog/mainwindow.cpp" line="724"/> <location filename="../Dialog/mainwindow.cpp" line="732"/>
<source>ProcessSuccess</source> <source>ProcessSuccess</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../Dialog/mainwindow.cpp" line="764"/> <location filename="../Dialog/mainwindow.cpp" line="846"/>
<location filename="../Dialog/mainwindow.cpp" line="1069"/> <location filename="../Dialog/mainwindow.cpp" line="1167"/>
<location filename="../Dialog/mainwindow.cpp" line="1082"/> <location filename="../Dialog/mainwindow.cpp" line="1181"/>
<location filename="../Dialog/mainwindow.cpp" line="1156"/> <location filename="../Dialog/mainwindow.cpp" line="1256"/>
<source>ChooseFile</source> <source>ChooseFile</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../Dialog/mainwindow.cpp" line="809"/> <location filename="../Dialog/mainwindow.cpp" line="891"/>
<location filename="../Dialog/mainwindow.cpp" line="1180"/> <location filename="../Dialog/mainwindow.cpp" line="1289"/>
<source>PleaseInputIndex</source> <source>PleaseInputIndex</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../Dialog/mainwindow.cpp" line="886"/> <location filename="../Dialog/mainwindow.cpp" line="979"/>
<location filename="../Dialog/mainwindow.cpp" line="1135"/> <location filename="../Dialog/mainwindow.cpp" line="1235"/>
<source>ChooseSaveFile</source> <source>ChooseSaveFile</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../Dialog/mainwindow.cpp" line="893"/> <location filename="../Dialog/mainwindow.cpp" line="987"/>
<source>SaveAsSuccess</source> <source>SaveAsSuccess</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../Dialog/mainwindow.cpp" line="927"/> <location filename="../Dialog/mainwindow.cpp" line="1021"/>
<location filename="../Dialog/mainwindow.cpp" line="1144"/> <location filename="../Dialog/mainwindow.cpp" line="1244"/>
<source>ExportSuccess</source> <source>ExportSuccess</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../Dialog/mainwindow.cpp" line="930"/> <location filename="../Dialog/mainwindow.cpp" line="1024"/>
<source>ExportFail</source> <source>ExportFail</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../Dialog/mainwindow.cpp" line="998"/> <location filename="../Dialog/mainwindow.cpp" line="1097"/>
<source>SaveSuccess</source> <source>SaveSuccess</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../Dialog/mainwindow.cpp" line="1039"/> <location filename="../Dialog/mainwindow.cpp" line="1138"/>
<source>DelayTime</source> <source>DelayTime</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../Dialog/mainwindow.cpp" line="1039"/> <location filename="../Dialog/mainwindow.cpp" line="1138"/>
<source>Input10ms</source> <source>Inputms</source>
<translation> 10ms</translation> <translation> ms</translation>
</message> </message>
<message> <message>
<location filename="../Dialog/mainwindow.cpp" line="1055"/> <source>Input10ms</source>
<translation type="vanished"> 10ms</translation>
</message>
<message>
<location filename="../Dialog/mainwindow.cpp" line="1153"/>
<source>ScaleDelayTime</source> <source>ScaleDelayTime</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../Dialog/mainwindow.cpp" line="1056"/> <location filename="../Dialog/mainwindow.cpp" line="1154"/>
<source>InputPercent</source> <source>InputPercent</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../Dialog/mainwindow.cpp" line="1069"/> <location filename="../Dialog/mainwindow.cpp" line="1167"/>
<source>Images (*.jpg *.tiff *.png)</source> <source>Images (*.jpg *.tiff *.png)</source>
<translation> (*.jpg *.tiff *.png)</translation> <translation> (*.jpg *.tiff *.png)</translation>
</message> </message>
<message> <message>
<location filename="../Dialog/mainwindow.cpp" line="1152"/> <location filename="../Dialog/mainwindow.cpp" line="1252"/>
<source>NoSelection</source> <source>NoSelection</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../Dialog/mainwindow.cpp" line="1172"/> <location filename="../Dialog/mainwindow.cpp" line="1282"/>
<source>InvalidModel</source> <source>InvalidModel</source>
<translation></translation> <translation></translation>
</message> </message>