├── .github └── FUNDING.yml ├── .qmake.stash ├── Makefile ├── NeuralStyler.ico ├── NeuralStyler.pro ├── NeuralStyler.pro.user ├── README.md ├── WinVersion.h ├── aboutdialog.cpp ├── aboutdialog.h ├── aboutdialog.ui ├── ffmpegprocess.cpp ├── ffmpegprocess.h ├── framedialog.cpp ├── framedialog.h ├── framedialog.ui ├── images ├── fileopen.png ├── filesave .png ├── paint-cancel.png ├── paint.png ├── pause.png ├── preview.png └── wm.png ├── main.cpp ├── mplayer.cpp ├── mplayer.h ├── mpv ├── client.h ├── lib │ └── libmpv.dll.a ├── opengl_cb.h ├── qthelper.hpp └── stream_cb.h ├── myprocess.cpp ├── myprocess.h ├── neuralstyler ├── neuralstyler-help └── help │ ├── docs │ ├── hstyle.md │ ├── img │ │ ├── neuralstyler-save.jpg │ │ ├── neuralstyler1.jpg │ │ ├── styles.png │ │ └── videosection.PNG │ ├── index.md │ ├── options.md │ └── styles.md │ └── mkdocs.yml ├── neuralstyler-logo.jpg ├── neuralstyler.qrc ├── neuralstyler.rc ├── neuralstylerwindow.cpp ├── neuralstylerwindow.h ├── neuralstylerwindow.ui ├── paths.cpp ├── paths.h ├── python-part ├── generate.py └── net.py ├── qxtspanslider.cpp ├── qxtspanslider.h ├── qxtspanslider_p.h ├── stylechainer.cpp ├── stylechainer.h ├── styleintensitydialog.cpp ├── styleintensitydialog.h ├── styleintensitydialog.ui └── styles ├── cubist-style.jpg ├── cubist.model ├── edtaonisl-style.jpg ├── edtaonisl.model ├── hokusai-style.jpg ├── hokusai.model ├── hundertwasser-style.jpg ├── hundertwasser.model ├── kandinsky-style.jpg ├── kandinsky.model ├── seurat.model ├── starrynight-style.jpg └── starrynight.model /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [rupeshs] 4 | -------------------------------------------------------------------------------- /.qmake.stash: -------------------------------------------------------------------------------- 1 | QMAKE_DEFAULT_INCDIRS = \ 2 | /usr/include/c++/4.8 \ 3 | /usr/include/x86_64-linux-gnu/c++/4.8 \ 4 | /usr/include/c++/4.8/backward \ 5 | /usr/lib/gcc/x86_64-linux-gnu/4.8/include \ 6 | /usr/local/include \ 7 | /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed \ 8 | /usr/include/x86_64-linux-gnu \ 9 | /usr/include 10 | QMAKE_DEFAULT_LIBDIRS = \ 11 | /usr/lib/gcc/x86_64-linux-gnu/4.8 \ 12 | /usr/lib/x86_64-linux-gnu \ 13 | /usr/lib \ 14 | /lib/x86_64-linux-gnu \ 15 | /lib 16 | -------------------------------------------------------------------------------- /NeuralStyler.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rupeshs/neuralstyler/ff4986fc77f4be6a0a0b10e4a9dc60e6057d0487/NeuralStyler.ico -------------------------------------------------------------------------------- /NeuralStyler.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2016-08-07T08:48:11 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | 9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 10 | 11 | TARGET = NeuralStyler 12 | TEMPLATE = app 13 | 14 | 15 | SOURCES += main.cpp\ 16 | neuralstylerwindow.cpp \ 17 | ffmpegprocess.cpp \ 18 | paths.cpp \ 19 | stylechainer.cpp \ 20 | aboutdialog.cpp \ 21 | qxtspanslider.cpp \ 22 | styleintensitydialog.cpp \ 23 | framedialog.cpp \ 24 | mplayer.cpp \ 25 | myprocess.cpp 26 | 27 | HEADERS += neuralstylerwindow.h \ 28 | ffmpegprocess.h \ 29 | paths.h \ 30 | stylechainer.h \ 31 | aboutdialog.h \ 32 | WinVersion.h \ 33 | qxtspanslider_p.h \ 34 | qxtspanslider.h \ 35 | styleintensitydialog.h \ 36 | framedialog.h \ 37 | mplayer.h \ 38 | myprocess.h 39 | 40 | FORMS += neuralstylerwindow.ui \ 41 | aboutdialog.ui \ 42 | styleintensitydialog.ui \ 43 | framedialog.ui 44 | 45 | unix{ 46 | 47 | QMAKE_LFLAGS += -Wl,-rpath,"'\$$ORIGIN/../lib'" 48 | TARGET=neuralstyler 49 | 50 | } 51 | 52 | RESOURCES += \ 53 | neuralstyler.qrc 54 | RC_FILE = neuralstyler.rc 55 | -------------------------------------------------------------------------------- /NeuralStyler.pro.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | EnvironmentId 7 | {e14f30ee-bad2-4585-a4f9-31d95094fa90} 8 | 9 | 10 | ProjectExplorer.Project.ActiveTarget 11 | 0 12 | 13 | 14 | ProjectExplorer.Project.EditorSettings 15 | 16 | true 17 | false 18 | true 19 | 20 | Cpp 21 | 22 | CppGlobal 23 | 24 | 25 | 26 | QmlJS 27 | 28 | QmlJSGlobal 29 | 30 | 31 | 2 32 | UTF-8 33 | false 34 | 4 35 | false 36 | 80 37 | true 38 | true 39 | 1 40 | true 41 | false 42 | 0 43 | true 44 | true 45 | 0 46 | 8 47 | true 48 | 1 49 | true 50 | true 51 | true 52 | false 53 | 54 | 55 | 56 | ProjectExplorer.Project.PluginSettings 57 | 58 | 59 | 60 | ProjectExplorer.Project.Target.0 61 | 62 | Desktop Qt 5.7.0 GCC 64bit 63 | Desktop Qt 5.7.0 GCC 64bit 64 | qt.57.gcc_64_kit 65 | 1 66 | 0 67 | 0 68 | 69 | /home/rupesh/neuralstyler/neuralstyler 70 | 71 | 72 | true 73 | qmake 74 | 75 | QtProjectManager.QMakeBuildStep 76 | true 77 | 78 | false 79 | false 80 | false 81 | 82 | 83 | true 84 | Make 85 | 86 | Qt4ProjectManager.MakeStep 87 | 88 | -w 89 | -r 90 | 91 | false 92 | 93 | 94 | 95 | 2 96 | Build 97 | 98 | ProjectExplorer.BuildSteps.Build 99 | 100 | 101 | 102 | true 103 | Make 104 | 105 | Qt4ProjectManager.MakeStep 106 | 107 | -w 108 | -r 109 | 110 | true 111 | clean 112 | 113 | 114 | 1 115 | Clean 116 | 117 | ProjectExplorer.BuildSteps.Clean 118 | 119 | 2 120 | false 121 | 122 | Debug 123 | 124 | Qt4ProjectManager.Qt4BuildConfiguration 125 | 2 126 | true 127 | 128 | 129 | /home/rupesh/neuralstyler/neuralstyler 130 | 131 | 132 | true 133 | qmake 134 | 135 | QtProjectManager.QMakeBuildStep 136 | false 137 | 138 | false 139 | false 140 | false 141 | 142 | 143 | true 144 | Make 145 | 146 | Qt4ProjectManager.MakeStep 147 | 148 | -w 149 | -r 150 | 151 | false 152 | 153 | 154 | 155 | 2 156 | Build 157 | 158 | ProjectExplorer.BuildSteps.Build 159 | 160 | 161 | 162 | true 163 | Make 164 | 165 | Qt4ProjectManager.MakeStep 166 | 167 | -w 168 | -r 169 | 170 | true 171 | clean 172 | 173 | 174 | 1 175 | Clean 176 | 177 | ProjectExplorer.BuildSteps.Clean 178 | 179 | 2 180 | false 181 | 182 | Release 183 | 184 | Qt4ProjectManager.Qt4BuildConfiguration 185 | 0 186 | true 187 | 188 | 189 | /home/rupesh/neuralstyler/build-NeuralStyler-Desktop_Qt_5_7_0_GCC_64bit-Profile 190 | 191 | 192 | true 193 | qmake 194 | 195 | QtProjectManager.QMakeBuildStep 196 | true 197 | 198 | false 199 | true 200 | false 201 | 202 | 203 | true 204 | Make 205 | 206 | Qt4ProjectManager.MakeStep 207 | 208 | -w 209 | -r 210 | 211 | false 212 | 213 | 214 | 215 | 2 216 | Build 217 | 218 | ProjectExplorer.BuildSteps.Build 219 | 220 | 221 | 222 | true 223 | Make 224 | 225 | Qt4ProjectManager.MakeStep 226 | 227 | -w 228 | -r 229 | 230 | true 231 | clean 232 | 233 | 234 | 1 235 | Clean 236 | 237 | ProjectExplorer.BuildSteps.Clean 238 | 239 | 2 240 | false 241 | 242 | Profile 243 | 244 | Qt4ProjectManager.Qt4BuildConfiguration 245 | 0 246 | true 247 | 248 | 3 249 | 250 | 251 | 0 252 | Deploy 253 | 254 | ProjectExplorer.BuildSteps.Deploy 255 | 256 | 1 257 | Deploy locally 258 | 259 | ProjectExplorer.DefaultDeployConfiguration 260 | 261 | 1 262 | 263 | 264 | false 265 | false 266 | 1000 267 | 268 | true 269 | 270 | false 271 | false 272 | false 273 | false 274 | true 275 | 0.01 276 | 10 277 | true 278 | 1 279 | 25 280 | 281 | 1 282 | true 283 | false 284 | true 285 | valgrind 286 | 287 | 0 288 | 1 289 | 2 290 | 3 291 | 4 292 | 5 293 | 6 294 | 7 295 | 8 296 | 9 297 | 10 298 | 11 299 | 12 300 | 13 301 | 14 302 | 303 | 2 304 | 305 | NeuralStyler 306 | 307 | Qt4ProjectManager.Qt4RunConfiguration:/home/rupesh/neuralstyler/neuralstyler/NeuralStyler.pro 308 | true 309 | 310 | NeuralStyler.pro 311 | false 312 | 313 | /home/rupesh/neuralstyler/neuralstyler 314 | 3768 315 | false 316 | true 317 | false 318 | false 319 | true 320 | 321 | 1 322 | 323 | 324 | 325 | ProjectExplorer.Project.TargetCount 326 | 1 327 | 328 | 329 | ProjectExplorer.Project.Updater.FileVersion 330 | 18 331 | 332 | 333 | Version 334 | 18 335 | 336 | 337 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## NeuralStyler - Turn Your Videos/photos into Artwork 2 | 3 | NeuralStyler Artificial Intelligence converts your videos into art works by using styles of famous artists: Van Gogh,Wassily Kandinsky,Georges Seurat etc 4 | 5 | Features 6 | -------- 7 | * Style videos,gif animation and photos 8 | * No need to upload videos (Offline processing) 9 | * Faster AI styling algorithm 10 | * Extensible styling system(Plugin) 11 | 12 | ## Dependencies 13 | * Qt 5.x 14 | * Python 2.7 (Virtualenv for Ubuntu,WinPython 64 bit for Windows) 15 | * Chainer 16 | * ffmpeg 17 | 18 | ## How to install style 19 | Simply download the zip file and extract it you will get two files
20 | **style_name.model** 21 | **style_name-style.jpg** 22 | copy these two files to the styles folder and run NeuralStyler. 23 | 24 | ## Create your own styles 25 | Please read the neural network training instructions 26 | [Read](https://github.com/yusuketomoto/chainer-fast-neuralstyle#train) 27 | 28 | ## Dependencies 29 | [Chainer](http://chainer.org)
30 | [Microsoft COCO dataset](http://mscoco.org/dataset/#download) 31 | 32 | python train.py -s (style_image_path) -d (training_dataset_path) -g (use_gpu ? gpu_id : -1) 33 | -------------------------------------------------------------------------------- /WinVersion.h: -------------------------------------------------------------------------------- 1 | /* 2 | NeuralStyler,Artistic style for your videos/photos 3 | Copyright(C) 2016 Rupesh Sreeraman 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | You should have received a copy of the GNU General Public License 13 | along with this program; if not, write to the Free Software 14 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 15 | */ 16 | 17 | #ifndef WINVERSION_H 18 | #define WINVERSION_H 19 | 20 | #define VER_FILEVERSION 2,0,0,0 21 | #define VER_FILEVERSION_STR "2.0.0.0\0" 22 | 23 | #define VER_PRODUCTVERSION 2,0,0,0 24 | #define VER_PRODUCTVERSION_STR "2.0.0.0\0" 25 | 26 | #define VER_COMPANYNAME_STR "Rupesh Sreeraman\0" 27 | #define VER_FILEDESCRIPTION_STR "NeuralStyler 2.0.0 \0" 28 | #define VER_INTERNALNAME_STR "neuralstyler\0" 29 | #define VER_LEGALCOPYRIGHT_STR "Copyright (c)2016 Rupesh Sreeraman\0" 30 | #define VER_ORIGINALFILENAME_STR "neuralstyler.exe\0" 31 | #define VER_PRODUCTNAME_STR "NeuralStyler\0" 32 | #define VER_COMPANYDOMAIN_STR "http://neuralstyler.com/" 33 | 34 | #endif // WINVERSION_H 35 | -------------------------------------------------------------------------------- /aboutdialog.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | NeuralStyler,Artistic style for your videos/photos 3 | Copyright(C) 2016 Rupesh Sreeraman 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | You should have received a copy of the GNU General Public License 13 | along with this program; if not, write to the Free Software 14 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 15 | */ 16 | #include "aboutdialog.h" 17 | #include "ui_aboutdialog.h" 18 | 19 | AboutDialog::AboutDialog(QWidget *parent) : 20 | QDialog(parent), 21 | ui(new Ui::AboutDialog) 22 | { 23 | ui->setupUi(this); 24 | } 25 | 26 | AboutDialog::~AboutDialog() 27 | { 28 | delete ui; 29 | } 30 | -------------------------------------------------------------------------------- /aboutdialog.h: -------------------------------------------------------------------------------- 1 | /* 2 | NeuralStyler,Artistic style for your videos/photos 3 | Copyright(C) 2016 Rupesh Sreeraman 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | You should have received a copy of the GNU General Public License 13 | along with this program; if not, write to the Free Software 14 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 15 | */ 16 | #ifndef ABOUTDIALOG_H 17 | #define ABOUTDIALOG_H 18 | 19 | #include 20 | 21 | namespace Ui { 22 | class AboutDialog; 23 | } 24 | 25 | class AboutDialog : public QDialog 26 | { 27 | Q_OBJECT 28 | 29 | public: 30 | explicit AboutDialog(QWidget *parent = 0); 31 | ~AboutDialog(); 32 | 33 | private: 34 | Ui::AboutDialog *ui; 35 | }; 36 | 37 | #endif // ABOUTDIALOG_H 38 | -------------------------------------------------------------------------------- /aboutdialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | AboutDialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 500 10 | 200 11 | 12 | 13 | 14 | 15 | 500 16 | 200 17 | 18 | 19 | 20 | 21 | 500 22 | 200 23 | 24 | 25 | 26 | About 27 | 28 | 29 | 30 | :/neuralstyler-logo.jpg:/neuralstyler-logo.jpg 31 | 32 | 33 | 34 | 35 | 100 36 | 160 37 | 341 38 | 32 39 | 40 | 41 | 42 | Qt::Horizontal 43 | 44 | 45 | QDialogButtonBox::Ok 46 | 47 | 48 | 49 | 50 | 51 | 140 52 | 20 53 | 351 54 | 141 55 | 56 | 57 | 58 | <html><head/><body><p><span style=" font-size:12pt; font-weight:600;">NeuralStyler v2.0.1</span></p><p>Artistic style for your videos/photos/GIF</p><p>FFmpeg Copyright © 2000-2015 the FFmpeg developers</p><p>For more styles <a href="http://www.neuralstyler.com"><span style=" text-decoration: underline; color:#0000ff;">www.neuralstyler.com</span></a></p><p>Copyright © 2016 <a href="https://github.com/rupeshs"><span style=" text-decoration: underline; color:#0000ff;">Rupesh Sreeraman</span></a></p><p><br/></p></body></html> 59 | 60 | 61 | true 62 | 63 | 64 | 65 | 66 | 67 | 10 68 | 20 69 | 111 70 | 101 71 | 72 | 73 | 74 | 75 | 76 | 77 | :/neuralstyler-logo.jpg 78 | 79 | 80 | true 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | buttonBox 90 | accepted() 91 | AboutDialog 92 | accept() 93 | 94 | 95 | 248 96 | 254 97 | 98 | 99 | 157 100 | 274 101 | 102 | 103 | 104 | 105 | buttonBox 106 | rejected() 107 | AboutDialog 108 | reject() 109 | 110 | 111 | 316 112 | 260 113 | 114 | 115 | 286 116 | 274 117 | 118 | 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /ffmpegprocess.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | NeuralStyler,Artistic style for your videos/photos 3 | Copyright(C) 2016 Rupesh Sreeraman 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | You should have received a copy of the GNU General Public License 13 | along with this program; if not, write to the Free Software 14 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 15 | */ 16 | #include "ffmpegprocess.h" 17 | 18 | FfmpegProcess::FfmpegProcess() 19 | { 20 | 21 | connect(this,SIGNAL(readyReadStandardError()),this,SLOT(readyReadStandardError())); 22 | 23 | } 24 | void FfmpegProcess::startFfmpeg() 25 | { 26 | //qDebug()<start("ffmpeg.exe",arguments()); 31 | #endif 32 | #ifdef Q_OS_LINUX 33 | this->start("./ffmpeg",arguments()); 34 | # endif 35 | // qDebug()<-1) { 47 | 48 | // qDebug()<-1) { 55 | 56 | // qDebug()<-1) { 60 | 61 | // qDebug()<-1) { 66 | strDuration=rx_duration.cap(1); 67 | //qDebug()< 21 | #include 22 | #include 23 | #include 24 | 25 | //frame= 52 fps=0.0 q=24.8 size=N/A time=00:00:02.16 bitrate=N/A dup=6 drop=0 26 | //Duration: 00:00:26.74 27 | static QRegExp rx_duration("Duration:\\s*(\\d+:\\d+:\\d*\\.\\d+)"); 28 | static QRegExp rx_fps("(\\d*\\.\\d+)*.fps"); 29 | static QRegExp rx_fps_num("(\\d+)*.fps"); 30 | static QRegExp rx_frame_ct("frame=\\s*(\\d+)"); 31 | static QRegExp rx_width("(\\d+)x.*"); 32 | static QRegExp rx_height(".*x(\\d+)"); 33 | class FfmpegProcess : public QProcess 34 | { 35 | Q_OBJECT 36 | public: 37 | FfmpegProcess(); 38 | void startFfmpeg(); 39 | inline QString getFps(){return strFps;} 40 | inline QString getDuration(){return strDuration;} 41 | signals: 42 | void gotFrame(QString frameNumber); 43 | public slots: 44 | void readyReadStandardError(); 45 | 46 | private: 47 | QString strFps; 48 | QString strDuration; 49 | QString strConsoleErr; 50 | 51 | }; 52 | 53 | #endif // FFMPEGPROCESS_H 54 | -------------------------------------------------------------------------------- /framedialog.cpp: -------------------------------------------------------------------------------- 1 | #include "framedialog.h" 2 | #include "ui_framedialog.h" 3 | 4 | FrameDialog::FrameDialog(QWidget *parent) : 5 | QDialog(parent), 6 | ui(new Ui::FrameDialog) 7 | { 8 | ui->setupUi(this); 9 | } 10 | 11 | FrameDialog::~FrameDialog() 12 | { 13 | delete ui; 14 | } 15 | void FrameDialog::LoadFrame(QString path) 16 | { 17 | ui->labelFrame->setPixmap(QPixmap(path)); 18 | } 19 | -------------------------------------------------------------------------------- /framedialog.h: -------------------------------------------------------------------------------- 1 | #ifndef FRAMEDIALOG_H 2 | #define FRAMEDIALOG_H 3 | 4 | #include 5 | 6 | namespace Ui { 7 | class FrameDialog; 8 | } 9 | 10 | class FrameDialog : public QDialog 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit FrameDialog(QWidget *parent = 0); 16 | ~FrameDialog(); 17 | 18 | private: 19 | Ui::FrameDialog *ui; 20 | public slots: 21 | void LoadFrame(QString path); 22 | }; 23 | 24 | #endif // FRAMEDIALOG_H 25 | -------------------------------------------------------------------------------- /framedialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | FrameDialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 320 10 | 240 11 | 12 | 13 | 14 | Styled Frame Preview 15 | 16 | 17 | 18 | 19 | 20 | background-color: rgb(0, 0, 0); 21 | font: 75 8pt "MS Shell Dlg 2"; 22 | color: rgb(255, 255, 255); 23 | 24 | 25 | Please wait... 26 | 27 | 28 | Qt::AlignCenter 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /images/fileopen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rupeshs/neuralstyler/ff4986fc77f4be6a0a0b10e4a9dc60e6057d0487/images/fileopen.png -------------------------------------------------------------------------------- /images/filesave .png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rupeshs/neuralstyler/ff4986fc77f4be6a0a0b10e4a9dc60e6057d0487/images/filesave .png -------------------------------------------------------------------------------- /images/paint-cancel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rupeshs/neuralstyler/ff4986fc77f4be6a0a0b10e4a9dc60e6057d0487/images/paint-cancel.png -------------------------------------------------------------------------------- /images/paint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rupeshs/neuralstyler/ff4986fc77f4be6a0a0b10e4a9dc60e6057d0487/images/paint.png -------------------------------------------------------------------------------- /images/pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rupeshs/neuralstyler/ff4986fc77f4be6a0a0b10e4a9dc60e6057d0487/images/pause.png -------------------------------------------------------------------------------- /images/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rupeshs/neuralstyler/ff4986fc77f4be6a0a0b10e4a9dc60e6057d0487/images/preview.png -------------------------------------------------------------------------------- /images/wm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rupeshs/neuralstyler/ff4986fc77f4be6a0a0b10e4a9dc60e6057d0487/images/wm.png -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | NeuralStyler,Artistic style for your videos/photos 3 | Copyright(C) 2016 Rupesh Sreeraman 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | You should have received a copy of the GNU General Public License 13 | along with this program; if not, write to the Free Software 14 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 15 | */ 16 | #include "neuralstylerwindow.h" 17 | #include 18 | 19 | int main(int argc, char *argv[]) 20 | { 21 | int currentExitCode = 0; 22 | do { 23 | QApplication a(argc, argv); 24 | NeuralStylerWindow w; 25 | w.show(); 26 | currentExitCode = a.exec(); 27 | } while( currentExitCode == NeuralStylerWindow::EXIT_CODE_REBOOT ); 28 | 29 | return currentExitCode; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /mplayer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | NeuralStyler,Artistic style for your videos/photos 3 | Copyright(C) 2016 Rupesh Sreeraman 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | You should have received a copy of the GNU General Public License 13 | along with this program; if not, write to the Free Software 14 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 15 | */ 16 | 17 | #include "mplayer.h" 18 | 19 | Mplayer::Mplayer() 20 | { 21 | 22 | 23 | mProcess=new MyProcess(); 24 | QObject::connect(mProcess,SIGNAL(lineAvailable(QByteArray)),this,SLOT(mplayerConsole(QByteArray))); 25 | // QObject::connect(mProcess,SIGNAL(finished(int)),this,SLOT(emitProcessFinished(int))); 26 | 27 | } 28 | 29 | //Life of MPlayer 30 | void Mplayer::mplayerConsole(QByteArray ba) 31 | { 32 | //qDebug()<clearArguments(); 60 | 61 | #ifdef Q_OS_WIN 62 | argfrontEnd<<"-slave"<<"-identify"<<"-noquiet"<<"-priority"<<"abovenormal"; 63 | argfrontEnd<<"-vo"<<"direct3d,directx"; 64 | 65 | 66 | #endif 67 | #if defined(Q_OS_LINUX) || defined(Q_OS_OPENBSD) 68 | argfrontEnd<<"-slave"<<"-identify"<<"-noquiet"; 69 | #endif 70 | argfrontEnd<<"-volume"<<"0"; 71 | 72 | argfrontEnd<addArgument(mplayerPath); 77 | 78 | 79 | foreach (strArgument, argfrontEnd) { 80 | mProcess->addArgument(strArgument); 81 | } 82 | 83 | //qDebug()<< mProcess->arguments(); 84 | 85 | mProcess->start(); 86 | 87 | mProcess->write("osd 0\n"); 88 | mProcess->write("pause\n"); 89 | 90 | 91 | } 92 | 93 | QString Mplayer::parsevalue( QString serstr,QString sep,QString str) 94 | { 95 | QString tmp; 96 | tmp=str.mid(str.indexOf(serstr)); 97 | tmp=tmp.left(tmp.indexOf("\n")); 98 | 99 | qDebug()<<"Parsed ->"<write(cmd.toLatin1()+"\n"); 106 | //qDebug()< 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | class Mplayer:public QObject 29 | { 30 | Q_OBJECT 31 | 32 | public: 33 | 34 | Mplayer(); 35 | 36 | signals: 37 | void gotduration(float dur); 38 | public slots: 39 | void mplayerConsole(QByteArray ba); 40 | void setMplayerPath(QString path){mplayerPath=path;} 41 | void setVideoWin(long id); 42 | void setScaling(int width,int height); 43 | void play(QString filepath); 44 | QString parsevalue( QString serstr,QString sep,QString str); 45 | void command(QString cmd); 46 | private: 47 | QString mplayerPath; 48 | float _duration; 49 | QString tmpstr; 50 | MyProcess *mProcess; 51 | QStringList argfrontEnd; 52 | QTime _tduration; 53 | 54 | }; 55 | 56 | #endif // MPLAYER_H 57 | -------------------------------------------------------------------------------- /mpv/lib/libmpv.dll.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rupeshs/neuralstyler/ff4986fc77f4be6a0a0b10e4a9dc60e6057d0487/mpv/lib/libmpv.dll.a -------------------------------------------------------------------------------- /mpv/opengl_cb.h: -------------------------------------------------------------------------------- 1 | /* Permission to use, copy, modify, and/or distribute this software for any 2 | * purpose with or without fee is hereby granted, provided that the above 3 | * copyright notice and this permission notice appear in all copies. 4 | * 5 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 6 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 7 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 8 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 9 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 10 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 11 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | */ 13 | 14 | /* 15 | * Note: the client API is licensed under ISC (see above) to ease 16 | * interoperability with other licenses. But keep in mind that the 17 | * mpv core is still mostly GPLv2+. It's up to lawyers to decide 18 | * whether applications using this API are affected by the GPL. 19 | * One argument against this is that proprietary applications 20 | * using mplayer in slave mode is apparently tolerated, and this 21 | * API is basically equivalent to slave mode. 22 | */ 23 | 24 | #ifndef MPV_CLIENT_API_OPENGL_CB_H_ 25 | #define MPV_CLIENT_API_OPENGL_CB_H_ 26 | 27 | #include "client.h" 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | /** 34 | * Warning: this API is not stable yet. 35 | * 36 | * Overview 37 | * -------- 38 | * 39 | * This API can be used to make mpv render into a foreign OpenGL context. It 40 | * can be used to handle video display. Be aware that using this API is not 41 | * required: you can embed the mpv window by setting the mpv "wid" option to 42 | * a native window handle (see "Embedding the video window" section in the 43 | * client.h header). In general, using the "wid" option is recommended over 44 | * the OpenGL API, because it's simpler and more flexible on the mpv side. 45 | * 46 | * The renderer needs to be explicitly initialized with mpv_opengl_cb_init_gl(), 47 | * and then video can be drawn with mpv_opengl_cb_draw(). The user thread can 48 | * be notified by new frames with mpv_opengl_cb_set_update_callback(). 49 | * 50 | * OpenGL interop 51 | * -------------- 52 | * 53 | * This assumes the OpenGL context lives on a certain thread controlled by the 54 | * API user. The following functions require access to the OpenGL context: 55 | * mpv_opengl_cb_init_gl 56 | * mpv_opengl_cb_draw 57 | * mpv_opengl_cb_uninit_gl 58 | * 59 | * The OpenGL context is indirectly accessed through the OpenGL function 60 | * pointers returned by the get_proc_address callback in mpv_opengl_cb_init_gl. 61 | * Generally, mpv will not load the system OpenGL library when using this API. 62 | * 63 | * Only "desktop" OpenGL version 2.1 or later is supported. With OpenGL 2.1, 64 | * the GL_ARB_texture_rg is required. The renderer was written against 65 | * OpenGL 3.x core profile, with additional support for OpenGL 2.1. 66 | * 67 | * Note that some hardware decoding interop API (as set with the "hwdec" option) 68 | * may actually access 69 | * 70 | * OpenGL state 71 | * ------------ 72 | * 73 | * OpenGL has a large amount of implicit state. All the mpv functions mentioned 74 | * above expect that the OpenGL state is reasonably set to OpenGL standard 75 | * defaults. Likewise, mpv will attempt to leave the OpenGL context with 76 | * standard defaults. The following state is excluded from this: 77 | * 78 | * - the current viewport (can have/is set to an arbitrary value) 79 | * 80 | * Messing with the state could be avoided by creating shared OpenGL contexts, 81 | * but this is avoided for the sake of compatibility and interoperability. 82 | * 83 | * On OpenGL 2.1, mpv will strictly call functions like glGenTextures() to 84 | * create OpenGL objects. You will have to do the same. This ensures that 85 | * objects created by mpv and the API users don't clash. 86 | * 87 | * Threading 88 | * --------- 89 | * 90 | * The mpv_opengl_cb_* functions can be called from any thread, under the 91 | * following conditions: 92 | * - only one of the mpv_opengl_cb_* functions can be called at the same time 93 | * (unless they belong to different mpv cores created by mpv_create()) 94 | * - for functions which need an OpenGL context (see above) the OpenGL context 95 | * must be "current" in the current thread, and it must be the same context 96 | * as used with mpv_opengl_cb_init_gl() 97 | * - never can be called from within the callbacks set with 98 | * mpv_set_wakeup_callback() or mpv_opengl_cb_set_update_callback() 99 | * 100 | * Context and handle lifecycle 101 | * ---------------------------- 102 | * 103 | * Video initialization will fail if the OpenGL context was not initialized yet 104 | * (with mpv_opengl_cb_init_gl()). Likewise, mpv_opengl_cb_uninit_gl() will 105 | * disable video. 106 | * 107 | * When the mpv core is destroyed (e.g. via mpv_terminate_destroy()), the OpenGL 108 | * context must have been uninitialized. If this doesn't happen, undefined 109 | * behavior will result. 110 | * 111 | * Hardware decoding 112 | * ----------------- 113 | * 114 | * Hardware decoding via opengl_cb is fully supported, but requires some 115 | * additional setup. (At least if direct hardware decoding modes are wanted, 116 | * instead of copying back surface data from GPU to CPU RAM.) 117 | * 118 | * While "normal" mpv loads the OpenGL hardware decoding interop on demand, 119 | * this can't be done with opengl_cb for internal technical reasons. Instead, 120 | * make it load the interop at load time by setting the "hwdec-preload"="auto" 121 | * option before calling mpv_opengl_cb_init_gl(). 122 | * 123 | * There may be certain requirements on the OpenGL implementation: 124 | * - Windows: ANGLE is required (although in theory GL/DX interop could be used) 125 | * - Intel/Linux: EGL is required, and also a glMPGetNativeDisplay() callback 126 | * must be provided (see sections below) 127 | * - nVidia/Linux: GLX is required 128 | * - OSX: CGL is required (CGLGetCurrentContext() returning non-NULL) 129 | * 130 | * Once these things are setup, hardware decoding can be enabled/disabled at 131 | * any time by setting the "hwdec" property. 132 | * 133 | * Special windowing system interop considerations 134 | * ------------------------------------------------ 135 | * 136 | * In some cases, libmpv needs to have access to the windowing system's handles. 137 | * This can be a pointer to a X11 "Display" for example. Usually this is needed 138 | * only for hardware decoding. 139 | * 140 | * You can communicate these handles to libmpv by adding a pseudo-OpenGL 141 | * extension "GL_MP_MPGetNativeDisplay" to the additional extension string when 142 | * calling mpv_opengl_cb_init_gl(). The get_proc_address callback should resolve 143 | * a function named "glMPGetNativeDisplay", which has the signature: 144 | * 145 | * void* GLAPIENTRY glMPGetNativeDisplay(const char* name) 146 | * 147 | * See below what names are defined. Usually, libmpv will use the native handle 148 | * up until mpv_opengl_cb_uninit_gl() is called. If the name is not anything 149 | * you know/expected, return NULL from the function. 150 | * 151 | * Windowing system interop on Intel/Linux with VAAPI 152 | * -------------------------------------------------- 153 | * 154 | * The new VAAPI OpenGL interop requires an EGL context. EGL provides no way 155 | * to query the X11 Display associated to a specific EGL context, so this API 156 | * is used to pass it through. 157 | * 158 | * glMPGetNativeDisplay("x11") should return a X11 "Display*", which then will 159 | * be used to create the hardware decoder state. 160 | * 161 | * glMPGetNativeDisplay("wl") should return a Wayland "struct wl_display *". 162 | * 163 | * glMPGetNativeDisplay("drm") should return a DRM FD casted to intptr_t (note 164 | * that a 0 FD is not supported - if this can happen in your case, you must 165 | * dup2() it to a non-0 FD). 166 | * 167 | * nVidia/Linux via VDPAU requires GLX, which does not have this problem (the 168 | * GLX API can return the current X11 Display). 169 | * 170 | * Windowing system interop on MS win32 171 | * ------------------------------------ 172 | * 173 | * Warning: the following is only required if native OpenGL instead of ANGLE 174 | * is used. ANGLE is recommended, because it also allows direct 175 | * hardware decoding interop without further setup by the libmpv 176 | * API user, while the same with native OpenGL is either very hard 177 | * to do (via GL/DX interop with D3D9), or not implemented. 178 | * 179 | * If OpenGL switches to fullscreen, most players give it access GPU access, 180 | * which means DXVA2 hardware decoding in mpv won't work. This can be worked 181 | * around by giving mpv access to Direct3D device, which it will then use to 182 | * create a decoder. The device can be either the real device used for display, 183 | * or a "blank" device created before switching to fullscreen. 184 | * 185 | * You can provide glMPGetNativeDisplay as described in the previous section. 186 | * If it is called with name set to "IDirect3DDevice9", it should return a 187 | * IDirect3DDevice9 pointer (or NULL if not available). libmpv will release 188 | * this interface when it is done with it. 189 | * 190 | * In previous libmpv releases, this used "GL_MP_D3D_interfaces" and 191 | * "glMPGetD3DInterface". This is deprecated; use glMPGetNativeDisplay instead 192 | * (the semantics are 100% compatible). 193 | */ 194 | 195 | /** 196 | * Opaque context, returned by mpv_get_sub_api(MPV_SUB_API_OPENGL_CB). 197 | * 198 | * A context is bound to the mpv_handle it was retrieved from. The context 199 | * will always be the same (for the same mpv_handle), and is valid until the 200 | * mpv_handle it belongs to is released. 201 | */ 202 | typedef struct mpv_opengl_cb_context mpv_opengl_cb_context; 203 | 204 | typedef void (*mpv_opengl_cb_update_fn)(void *cb_ctx); 205 | typedef void *(*mpv_opengl_cb_get_proc_address_fn)(void *fn_ctx, const char *name); 206 | 207 | /** 208 | * Set the callback that notifies you when a new video frame is available, or 209 | * if the video display configuration somehow changed and requires a redraw. 210 | * Similar to mpv_set_wakeup_callback(), you must not call any mpv API from 211 | * the callback. 212 | * 213 | * @param callback callback(callback_ctx) is called if the frame should be 214 | * redrawn 215 | * @param callback_ctx opaque argument to the callback 216 | */ 217 | void mpv_opengl_cb_set_update_callback(mpv_opengl_cb_context *ctx, 218 | mpv_opengl_cb_update_fn callback, 219 | void *callback_ctx); 220 | 221 | /** 222 | * Initialize the mpv OpenGL state. This retrieves OpenGL function pointers via 223 | * get_proc_address, and creates OpenGL objects needed by mpv internally. It 224 | * will also call APIs needed for rendering hardware decoded video in OpenGL, 225 | * according to the mpv "hwdec" option. 226 | * 227 | * You must free the associated state at some point by calling the 228 | * mpv_opengl_cb_uninit_gl() function. Not doing so may result in memory leaks 229 | * or worse. 230 | * 231 | * @param exts optional _additional_ extension string, can be NULL 232 | * @param get_proc_address callback used to retrieve function pointers to OpenGL 233 | * functions. This is used for both standard functions 234 | * and extension functions. (The extension string is 235 | * checked whether extensions are really available.) 236 | * The callback will be called from this function only 237 | * (it is not stored and never used later). 238 | * Usually, GL context APIs do this for you (e.g. with 239 | * glXGetProcAddressARB or wglGetProcAddress), but 240 | * some APIs do not always return pointers for all 241 | * standard functions (even if present); in this case 242 | * you have to compensate by looking up these functions 243 | * yourself. 244 | * @param get_proc_address_ctx arbitrary opaque user context passed to the 245 | * get_proc_address callback 246 | * @return error code (same as normal mpv_* API), including but not limited to: 247 | * MPV_ERROR_UNSUPPORTED: the OpenGL version is not supported 248 | * (or required extensions are missing) 249 | * MPV_ERROR_INVALID_PARAMETER: the OpenGL state was already initialized 250 | */ 251 | int mpv_opengl_cb_init_gl(mpv_opengl_cb_context *ctx, const char *exts, 252 | mpv_opengl_cb_get_proc_address_fn get_proc_address, 253 | void *get_proc_address_ctx); 254 | 255 | /** 256 | * Render video. Requires that the OpenGL state is initialized. 257 | * 258 | * The video will use the full provided framebuffer. Options like "panscan" are 259 | * applied to determine which part of the video should be visible and how the 260 | * video should be scaled. You can change these options at runtime by using the 261 | * mpv property API. 262 | * 263 | * The renderer will reconfigure itself every time the output rectangle/size 264 | * is changed. (If you want to do animations, it might be better to do the 265 | * animation on a FBO instead.) 266 | * 267 | * This function implicitly pulls a video frame from the internal queue and 268 | * renders it. If no new frame is available, the previous frame is redrawn. 269 | * The update callback set with mpv_opengl_cb_set_update_callback() notifies 270 | * you when a new frame was added. 271 | * 272 | * @param fbo The framebuffer object to render on. Because the renderer might 273 | * manage multiple FBOs internally for the purpose of video 274 | * postprocessing, it will always bind and unbind FBOs itself. If 275 | * you want mpv to render on the main framebuffer, pass 0. 276 | * @param w Width of the framebuffer. This is either the video size if the fbo 277 | * parameter is 0, or the allocated size of the texture backing the 278 | * fbo. The renderer will always use the full size of the fbo. 279 | * @param h Height of the framebuffer. Same as with the w parameter, except 280 | * that this parameter can be negative. In this case, the video 281 | * frame will be rendered flipped. 282 | * @return 0 283 | */ 284 | int mpv_opengl_cb_draw(mpv_opengl_cb_context *ctx, int fbo, int w, int h); 285 | 286 | /** 287 | * Deprecated. Use mpv_opengl_cb_draw(). This function is equivalent to: 288 | * 289 | * int mpv_opengl_cb_render(mpv_opengl_cb_context *ctx, int fbo, int vp[4]) 290 | * { return mpv_opengl_cb_draw(ctx, fbo, vp[2], vp[3]); } 291 | * 292 | * vp[0] and vp[1] used to have a meaning, but are ignored in newer versions. 293 | * 294 | * This function will be removed in the future without version bump (this API 295 | * was never marked as stable). 296 | */ 297 | int mpv_opengl_cb_render(mpv_opengl_cb_context *ctx, int fbo, int vp[4]); 298 | 299 | /** 300 | * Tell the renderer that a frame was flipped at the given time. This is 301 | * optional, but can help the player to achieve better timing. 302 | * 303 | * Note that calling this at least once informs libmpv that you will use this 304 | * function. If you use it inconsistently, expect bad video playback. 305 | * 306 | * If this is called while no video or no OpenGL is initialized, it is ignored. 307 | * 308 | * @param time The mpv time (using mpv_get_time_us()) at which the flip call 309 | * returned. If 0 is passed, mpv_get_time_us() is used instead. 310 | * Currently, this parameter is ignored. 311 | * @return error code 312 | */ 313 | int mpv_opengl_cb_report_flip(mpv_opengl_cb_context *ctx, int64_t time); 314 | 315 | /** 316 | * Destroy the mpv OpenGL state. 317 | * 318 | * If video is still active (e.g. a file playing), video will be disabled 319 | * forcefully. 320 | * 321 | * Calling this multiple times is ok. 322 | * 323 | * @return error code 324 | */ 325 | int mpv_opengl_cb_uninit_gl(mpv_opengl_cb_context *ctx); 326 | 327 | #ifdef __cplusplus 328 | } 329 | #endif 330 | 331 | #endif 332 | -------------------------------------------------------------------------------- /mpv/qthelper.hpp: -------------------------------------------------------------------------------- 1 | /* Permission to use, copy, modify, and/or distribute this software for any 2 | * purpose with or without fee is hereby granted, provided that the above 3 | * copyright notice and this permission notice appear in all copies. 4 | * 5 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 6 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 7 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 8 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 9 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 10 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 11 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | */ 13 | 14 | /** 15 | * Note: these helpers are provided for convenience for C++/Qt applications. 16 | * This is based on the public API in client.h, and it does not encode any 17 | * knowledge that is not known or guaranteed outside of the C client API. You 18 | * can even copy and modify this code as you like, or implement similar things 19 | * for other languages. 20 | */ 21 | 22 | #ifndef MPV_CLIENT_API_QTHELPER_H_ 23 | #define MPV_CLIENT_API_QTHELPER_H_ 24 | 25 | #include 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | 35 | namespace mpv { 36 | namespace qt { 37 | 38 | // Wrapper around mpv_handle. Does refcounting under the hood. 39 | class Handle 40 | { 41 | struct container { 42 | container(mpv_handle *h) : mpv(h) {} 43 | ~container() { mpv_terminate_destroy(mpv); } 44 | mpv_handle *mpv; 45 | }; 46 | QSharedPointer sptr; 47 | public: 48 | // Construct a new Handle from a raw mpv_handle with refcount 1. If the 49 | // last Handle goes out of scope, the mpv_handle will be destroyed with 50 | // mpv_terminate_destroy(). 51 | // Never destroy the mpv_handle manually when using this wrapper. You 52 | // will create dangling pointers. Just let the wrapper take care of 53 | // destroying the mpv_handle. 54 | // Never create multiple wrappers from the same raw mpv_handle; copy the 55 | // wrapper instead (that's what it's for). 56 | static Handle FromRawHandle(mpv_handle *handle) { 57 | Handle h; 58 | h.sptr = QSharedPointer(new container(handle)); 59 | return h; 60 | } 61 | 62 | // Return the raw handle; for use with the libmpv C API. 63 | operator mpv_handle*() const { return sptr ? (*sptr).mpv : 0; } 64 | }; 65 | 66 | static inline QVariant node_to_variant(const mpv_node *node) 67 | { 68 | switch (node->format) { 69 | case MPV_FORMAT_STRING: 70 | return QVariant(QString::fromUtf8(node->u.string)); 71 | case MPV_FORMAT_FLAG: 72 | return QVariant(static_cast(node->u.flag)); 73 | case MPV_FORMAT_INT64: 74 | return QVariant(static_cast(node->u.int64)); 75 | case MPV_FORMAT_DOUBLE: 76 | return QVariant(node->u.double_); 77 | case MPV_FORMAT_NODE_ARRAY: { 78 | mpv_node_list *list = node->u.list; 79 | QVariantList qlist; 80 | for (int n = 0; n < list->num; n++) 81 | qlist.append(node_to_variant(&list->values[n])); 82 | return QVariant(qlist); 83 | } 84 | case MPV_FORMAT_NODE_MAP: { 85 | mpv_node_list *list = node->u.list; 86 | QVariantMap qmap; 87 | for (int n = 0; n < list->num; n++) { 88 | qmap.insert(QString::fromUtf8(list->keys[n]), 89 | node_to_variant(&list->values[n])); 90 | } 91 | return QVariant(qmap); 92 | } 93 | default: // MPV_FORMAT_NONE, unknown values (e.g. future extensions) 94 | return QVariant(); 95 | } 96 | } 97 | 98 | struct node_builder { 99 | node_builder(const QVariant& v) { 100 | set(&node_, v); 101 | } 102 | ~node_builder() { 103 | free_node(&node_); 104 | } 105 | mpv_node *node() { return &node_; } 106 | private: 107 | Q_DISABLE_COPY(node_builder) 108 | mpv_node node_; 109 | mpv_node_list *create_list(mpv_node *dst, bool is_map, int num) { 110 | dst->format = is_map ? MPV_FORMAT_NODE_MAP : MPV_FORMAT_NODE_ARRAY; 111 | mpv_node_list *list = new mpv_node_list(); 112 | dst->u.list = list; 113 | if (!list) 114 | goto err; 115 | list->values = new mpv_node[num](); 116 | if (!list->values) 117 | goto err; 118 | if (is_map) { 119 | list->keys = new char*[num](); 120 | if (!list->keys) 121 | goto err; 122 | } 123 | return list; 124 | err: 125 | free_node(dst); 126 | return NULL; 127 | } 128 | char *dup_qstring(const QString &s) { 129 | QByteArray b = s.toUtf8(); 130 | char *r = new char[b.size() + 1]; 131 | if (r) 132 | std::memcpy(r, b.data(), b.size() + 1); 133 | return r; 134 | } 135 | bool test_type(const QVariant &v, QMetaType::Type t) { 136 | // The Qt docs say: "Although this function is declared as returning 137 | // "QVariant::Type(obsolete), the return value should be interpreted 138 | // as QMetaType::Type." 139 | // So a cast really seems to be needed to avoid warnings (urgh). 140 | return static_cast(v.type()) == static_cast(t); 141 | } 142 | void set(mpv_node *dst, const QVariant &src) { 143 | if (test_type(src, QMetaType::QString)) { 144 | dst->format = MPV_FORMAT_STRING; 145 | dst->u.string = dup_qstring(src.toString()); 146 | if (!dst->u.string) 147 | goto fail; 148 | } else if (test_type(src, QMetaType::Bool)) { 149 | dst->format = MPV_FORMAT_FLAG; 150 | dst->u.flag = src.toBool() ? 1 : 0; 151 | } else if (test_type(src, QMetaType::Int) || 152 | test_type(src, QMetaType::LongLong) || 153 | test_type(src, QMetaType::UInt) || 154 | test_type(src, QMetaType::ULongLong)) 155 | { 156 | dst->format = MPV_FORMAT_INT64; 157 | dst->u.int64 = src.toLongLong(); 158 | } else if (test_type(src, QMetaType::Double)) { 159 | dst->format = MPV_FORMAT_DOUBLE; 160 | dst->u.double_ = src.toDouble(); 161 | } else if (src.canConvert()) { 162 | QVariantList qlist = src.toList(); 163 | mpv_node_list *list = create_list(dst, false, qlist.size()); 164 | if (!list) 165 | goto fail; 166 | list->num = qlist.size(); 167 | for (int n = 0; n < qlist.size(); n++) 168 | set(&list->values[n], qlist[n]); 169 | } else if (src.canConvert()) { 170 | QVariantMap qmap = src.toMap(); 171 | mpv_node_list *list = create_list(dst, true, qmap.size()); 172 | if (!list) 173 | goto fail; 174 | list->num = qmap.size(); 175 | for (int n = 0; n < qmap.size(); n++) { 176 | list->keys[n] = dup_qstring(qmap.keys()[n]); 177 | if (!list->keys[n]) { 178 | free_node(dst); 179 | goto fail; 180 | } 181 | set(&list->values[n], qmap.values()[n]); 182 | } 183 | } else { 184 | goto fail; 185 | } 186 | return; 187 | fail: 188 | dst->format = MPV_FORMAT_NONE; 189 | } 190 | void free_node(mpv_node *dst) { 191 | switch (dst->format) { 192 | case MPV_FORMAT_STRING: 193 | delete[] dst->u.string; 194 | break; 195 | case MPV_FORMAT_NODE_ARRAY: 196 | case MPV_FORMAT_NODE_MAP: { 197 | mpv_node_list *list = dst->u.list; 198 | if (list) { 199 | for (int n = 0; n < list->num; n++) { 200 | if (list->keys) 201 | delete[] list->keys[n]; 202 | if (list->values) 203 | free_node(&list->values[n]); 204 | } 205 | delete[] list->keys; 206 | delete[] list->values; 207 | } 208 | delete list; 209 | break; 210 | } 211 | default: ; 212 | } 213 | dst->format = MPV_FORMAT_NONE; 214 | } 215 | }; 216 | 217 | /** 218 | * RAII wrapper that calls mpv_free_node_contents() on the pointer. 219 | */ 220 | struct node_autofree { 221 | mpv_node *ptr; 222 | node_autofree(mpv_node *a_ptr) : ptr(a_ptr) {} 223 | ~node_autofree() { mpv_free_node_contents(ptr); } 224 | }; 225 | 226 | /** 227 | * Return the given property as mpv_node converted to QVariant, or QVariant() 228 | * on error. 229 | * 230 | * @param name the property name 231 | */ 232 | static inline QVariant get_property_variant(mpv_handle *ctx, const QString &name) 233 | { 234 | mpv_node node; 235 | if (mpv_get_property(ctx, name.toUtf8().data(), MPV_FORMAT_NODE, &node) < 0) 236 | return QVariant(); 237 | node_autofree f(&node); 238 | return node_to_variant(&node); 239 | } 240 | 241 | /** 242 | * Set the given property as mpv_node converted from the QVariant argument. 243 | */ 244 | static inline int set_property_variant(mpv_handle *ctx, const QString &name, 245 | const QVariant &v) 246 | { 247 | node_builder node(v); 248 | return mpv_set_property(ctx, name.toUtf8().data(), MPV_FORMAT_NODE, node.node()); 249 | } 250 | 251 | /** 252 | * Set the given option as mpv_node converted from the QVariant argument. 253 | */ 254 | static inline int set_option_variant(mpv_handle *ctx, const QString &name, 255 | const QVariant &v) 256 | { 257 | node_builder node(v); 258 | return mpv_set_option(ctx, name.toUtf8().data(), MPV_FORMAT_NODE, node.node()); 259 | } 260 | 261 | /** 262 | * mpv_command_node() equivalent. Returns QVariant() on error (and 263 | * unfortunately, the same on success). 264 | */ 265 | static inline QVariant command_variant(mpv_handle *ctx, const QVariant &args) 266 | { 267 | node_builder node(args); 268 | mpv_node res; 269 | if (mpv_command_node(ctx, node.node(), &res) < 0) 270 | return QVariant(); 271 | node_autofree f(&res); 272 | return node_to_variant(&res); 273 | } 274 | 275 | } 276 | } 277 | 278 | #endif 279 | -------------------------------------------------------------------------------- /mpv/stream_cb.h: -------------------------------------------------------------------------------- 1 | /* Permission to use, copy, modify, and/or distribute this software for any 2 | * purpose with or without fee is hereby granted, provided that the above 3 | * copyright notice and this permission notice appear in all copies. 4 | * 5 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 6 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 7 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 8 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 9 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 10 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 11 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 12 | */ 13 | 14 | /* 15 | * Note: the client API is licensed under ISC (see above) to ease 16 | * interoperability with other licenses. But keep in mind that the 17 | * mpv core is still mostly GPLv2+. It's up to lawyers to decide 18 | * whether applications using this API are affected by the GPL. 19 | * One argument against this is that proprietary applications 20 | * using mplayer in slave mode is apparently tolerated, and this 21 | * API is basically equivalent to slave mode. 22 | */ 23 | 24 | #ifndef MPV_CLIENT_API_STREAM_CB_H_ 25 | #define MPV_CLIENT_API_STREAM_CB_H_ 26 | 27 | #include "client.h" 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | /** 34 | * Warning: this API is not stable yet. 35 | * 36 | * Overview 37 | * -------- 38 | * 39 | * This API can be used to make mpv read from a stream with a custom 40 | * implementation. This interface is inspired by funopen on BSD and 41 | * fopencookie on linux. The stream is backed by user-defined callbacks 42 | * which can implement customized open, read, seek, size and close behaviors. 43 | * 44 | * Usage 45 | * ----- 46 | * 47 | * Register your stream callbacks with the mpv_stream_cb_add_ro() function. You 48 | * have to provide a mpv_stream_cb_open_ro_fn callback to it (open_fn argument). 49 | * 50 | * Once registered, you can `loadfile myprotocol://myfile`. Your open_fn will be 51 | * invoked with the URI and you must fill out the provided mpv_stream_cb_info 52 | * struct. This includes your stream callbacks (like read_fn), and an opaque 53 | * cookie, which will be passed as the first argument to all the remaining 54 | * stream callbacks. 55 | * 56 | * Note that your custom callbacks must not invoke libmpv APIs as that would 57 | * cause a deadlock. 58 | * 59 | * Stream lifetime 60 | * --------------- 61 | * 62 | * A stream remains valid until its close callback has been called. It's up to 63 | * libmpv to call the close callback, and the libmpv user cannot close it 64 | * directly with the stream_cb API. 65 | * 66 | * For example, if you consider your custom stream to become suddenly invalid 67 | * (maybe because the underlying stream died), libmpv will continue using your 68 | * stream. All you can do is returning errors from each callback, until libmpv 69 | * gives up and closes it. 70 | * 71 | * Protocol registration and lifetime 72 | * ---------------------------------- 73 | * 74 | * Protocols remain registered until the mpv instance is terminated. This means 75 | * in particular that it can outlive the mpv_handle that was used to register 76 | * it, but once mpv_terminate_destroy() is called, your registered callbacks 77 | * will not be called again. 78 | * 79 | * Protocol unregistration is finished after the mpv core has been destroyed 80 | * (e.g. after mpv_terminate_destroy() has returned). 81 | * 82 | * If you do not call mpv_terminate_destroy() yourself (e.g. plugin-style code), 83 | * you will have to deal with the registration or even streams outliving your 84 | * code. Here are some possible ways to do this: 85 | * - call mpv_terminate_destroy(), which destroys the core, and will make sure 86 | * all streams are closed once this function returns 87 | * - you refcount all resources your stream "cookies" reference, so that it 88 | * doesn't matter if streams live longer than expected 89 | * - create "cancellation" semantics: after your protocol has been unregistered, 90 | * notify all your streams that are still opened, and make them drop all 91 | * referenced resources - then return errors from the stream callbacks as 92 | * long as the stream is still opened 93 | * 94 | */ 95 | 96 | /** 97 | * Read callback used to implement a custom stream. The semantics of the 98 | * callback match read(2) in blocking mode. Short reads are allowed (you can 99 | * return less bytes than requested, and libmpv will retry reading the rest 100 | * with a nother call). If no data can be immediately read, the callback must 101 | * block until there is new data. A return of 0 will be interpreted as final 102 | * EOF, although libmpv might retry the read, or seek to a different position. 103 | * 104 | * @param cookie opaque cookie identifying the stream, 105 | * returned from mpv_stream_cb_open_fn 106 | * @param buf buffer to read data into 107 | * @param size of the buffer 108 | * @return number of bytes read into the buffer 109 | * @return 0 on EOF 110 | * @return -1 on error 111 | */ 112 | typedef int64_t (*mpv_stream_cb_read_fn)(void *cookie, char *buf, uint64_t nbytes); 113 | 114 | /** 115 | * Seek callback used to implement a custom stream. 116 | * 117 | * Note that mpv will issue a seek to position 0 immediately after opening. This 118 | * is used to test whether the stream is seekable (since seekability might 119 | * depend on the URI contents, not just the protocol). Return 120 | * MPV_ERROR_UNSUPPORTED if seeking is not implemented for this stream. This 121 | * seek also servies to establish the fact that streams start at position 0. 122 | * 123 | * This callback can be NULL, in which it behaves as if always returning 124 | * MPV_ERROR_UNSUPPORTED. 125 | * 126 | * @param cookie opaque cookie identifying the stream, 127 | * returned from mpv_stream_cb_open_fn 128 | * @param offset target absolut stream position 129 | * @return the resulting offset of the stream 130 | * MPV_ERROR_UNSUPPORTED or MPV_ERROR_GENERIC if the seek failed 131 | */ 132 | typedef int64_t (*mpv_stream_cb_seek_fn)(void *cookie, int64_t offset); 133 | 134 | /** 135 | * Size callback used to implement a custom stream. 136 | * 137 | * Return MPV_ERROR_UNSUPPORTED if no size is known. 138 | * 139 | * This callback can be NULL, in which it behaves as if always returning 140 | * MPV_ERROR_UNSUPPORTED. 141 | * 142 | * @param cookie opaque cookie identifying the stream, 143 | * returned from mpv_stream_cb_open_fn 144 | * @return the total size in bytes of the stream 145 | */ 146 | typedef int64_t (*mpv_stream_cb_size_fn)(void *cookie); 147 | 148 | /** 149 | * Close callback used to implement a custom stream. 150 | * 151 | * @param cookie opaque cookie identifying the stream, 152 | * returned from mpv_stream_cb_open_fn 153 | */ 154 | typedef void (*mpv_stream_cb_close_fn)(void *cookie); 155 | 156 | /** 157 | * See mpv_stream_cb_open_ro_fn callback. 158 | */ 159 | typedef struct mpv_stream_cb_info { 160 | /** 161 | * Opaque user-provided value, which will be passed to the other callbacks. 162 | * The close callback will be called to release the cookie. It is not 163 | * interpreted by mpv. It doesn't even need to be a valid pointer. 164 | * 165 | * The user sets this in the mpv_stream_cb_open_ro_fn callback. 166 | */ 167 | void *cookie; 168 | 169 | /** 170 | * Callbacks set by the user in the mpv_stream_cb_open_ro_fn callback. Some 171 | * of them are optional, and can be left unset. 172 | * 173 | * The following callbacks are mandatory: read_fn, close_fn 174 | */ 175 | mpv_stream_cb_read_fn read_fn; 176 | mpv_stream_cb_seek_fn seek_fn; 177 | mpv_stream_cb_size_fn size_fn; 178 | mpv_stream_cb_close_fn close_fn; 179 | } mpv_stream_cb_info; 180 | 181 | /** 182 | * Open callback used to implement a custom read-only (ro) stream. The user 183 | * must set the callback fields in the passed info struct. The cookie field 184 | * also can be set to store state associated to the stream instance. 185 | * 186 | * Note that the info struct is valid only for the duration of this callback. 187 | * You can't change the callbacks or the pointer to the cookie at a later point. 188 | * 189 | * Each stream instance created by the open callback can have different 190 | * callbacks. 191 | * 192 | * The close_fn callback will terminate the stream instance. The pointers to 193 | * your callbacks and cookie will be discarded, and the callbacks will not be 194 | * called again. 195 | * 196 | * @param user_data opaque user data provided via mpv_stream_cb_add() 197 | * @param uri name of the stream to be opened (with protocol prefix) 198 | * @param info fields which the user should fill 199 | * @return opaque cookie identifing the newly opened stream 200 | * @return 0 on success, MPV_ERROR_LOADING_FAILED if the URI cannot be opened. 201 | */ 202 | typedef int (*mpv_stream_cb_open_ro_fn)(void *user_data, char *uri, 203 | mpv_stream_cb_info *info); 204 | 205 | /** 206 | * Add a custom stream protocol. This will register a protocol handler under 207 | * the given protocol prefix, and invoke the given callbacks if an URI with the 208 | * matching protocol prefix is opened. 209 | * 210 | * The "ro" is for read-only - only read-only streams can be registered with 211 | * this function. 212 | * 213 | * The callback remains registered until the mpv core is registered. 214 | * 215 | * If a custom stream with the same name is already registered, then the 216 | * MPV_ERROR_INVALID_PARAMETER error is returned. 217 | * 218 | * @param protocol protocol prefix, for example "foo" for "foo://" URIs 219 | * @param user_data opaque pointer passed into the mpv_stream_cb_open_fn 220 | * callback. 221 | * @return error code 222 | */ 223 | int mpv_stream_cb_add_ro(mpv_handle *ctx, const char *protocol, void *user_data, 224 | mpv_stream_cb_open_ro_fn open_fn); 225 | 226 | #ifdef __cplusplus 227 | } 228 | #endif 229 | 230 | #endif 231 | -------------------------------------------------------------------------------- /myprocess.cpp: -------------------------------------------------------------------------------- 1 | /* smplayer, GUI front-end for mplayer. 2 | Copyright (C) 2006-2009 Ricardo Villalba 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | */ 18 | 19 | #include "myprocess.h" 20 | 21 | #ifdef Q_OS_WIN 22 | 23 | #if QT_VERSION < 0x040300 24 | #define USE_TEMP_FILE 1 25 | #else 26 | #define USE_TEMP_FILE 0 27 | #endif 28 | 29 | #else 30 | #define USE_TEMP_FILE 0 31 | #endif 32 | 33 | 34 | MyProcess::MyProcess(QObject * parent) : QProcess(parent) 35 | { 36 | clearArguments(); 37 | setProcessChannelMode( QProcess::MergedChannels ); 38 | 39 | #if USE_TEMP_FILE 40 | temp_file.open(); // Create temporary file 41 | QString filename = temp_file.fileName(); 42 | setStandardOutputFile( filename ); 43 | qDebug("MyProcess::MyProcess: temporary file: %s", filename.toUtf8().data()); 44 | temp_file.close(); 45 | 46 | //connect(&temp_file, SIGNAL(readyRead()), this, SLOT(readTmpFile()) ); 47 | connect(&timer, SIGNAL(timeout()), this, SLOT(readTmpFile()) ); 48 | #else 49 | connect(this, SIGNAL(readyReadStandardOutput()), this, SLOT(readStdOut()) ); 50 | #endif 51 | 52 | connect(this, SIGNAL(finished(int, QProcess::ExitStatus)), 53 | this, SLOT(procFinished()) ); 54 | 55 | // Test splitArguments 56 | //QStringList l = MyProcess::splitArguments("-opt 1 hello \"56 67\" wssx -ios"); 57 | } 58 | 59 | void MyProcess::clearArguments() { 60 | program = ""; 61 | arg.clear(); 62 | } 63 | 64 | bool MyProcess::isRunning() { 65 | return (state() == QProcess::Running); 66 | } 67 | 68 | void MyProcess::addArgument(const QString & a) { 69 | if (program.isEmpty()) { 70 | program = a; 71 | } else { 72 | arg.append(a); 73 | } 74 | } 75 | 76 | QStringList MyProcess::arguments() { 77 | QStringList l = arg; 78 | l.prepend(program); 79 | return l; 80 | } 81 | 82 | void MyProcess::start() { 83 | remaining_output.clear(); 84 | 85 | QProcess::start(program, arg); 86 | 87 | #if USE_TEMP_FILE 88 | //bool r = temp_file.open(QIODevice::ReadOnly); 89 | bool r = temp_file.open(); 90 | timer.start(50); 91 | qDebug("MyProcess::start: r: %d", r); 92 | #endif 93 | } 94 | 95 | void MyProcess::readStdOut() { 96 | genericRead( readAllStandardOutput() ); 97 | } 98 | 99 | 100 | void MyProcess::readTmpFile() { 101 | genericRead( temp_file.readAll() ); 102 | } 103 | 104 | void MyProcess::genericRead(QByteArray buffer) { 105 | QByteArray ba = remaining_output + buffer; 106 | int start = 0; 107 | int from_pos = 0; 108 | int pos = canReadLine(ba, from_pos); 109 | 110 | //qDebug("MyProcess::read: pos: %d", pos); 111 | while ( pos > -1 ) { 112 | // Readline 113 | //QByteArray line = ba.left(pos); 114 | QByteArray line = ba.mid(start, pos-start); 115 | //ba = ba.mid(pos+1); 116 | from_pos = pos + 1; 117 | #ifdef Q_OS_WIN 118 | if ((from_pos < ba.size()) && (ba.at(from_pos)=='\n')) from_pos++; 119 | #endif 120 | start = from_pos; 121 | 122 | emit lineAvailable(line); 123 | 124 | pos = canReadLine(ba, from_pos); 125 | } 126 | 127 | remaining_output = ba.mid(from_pos); 128 | } 129 | 130 | int MyProcess::canReadLine(const QByteArray & ba, int from) { 131 | int pos1 = ba.indexOf('\n', from); 132 | int pos2 = ba.indexOf('\r', from); 133 | 134 | //qDebug("MyProcess::canReadLine: pos2: %d", pos2); 135 | 136 | if ( (pos1 == -1) && (pos2 == -1) ) return -1; 137 | 138 | int pos = pos1; 139 | if ( (pos1 != -1) && (pos2 != -1) ) { 140 | /* 141 | if (pos2 == (pos1+1)) pos = pos2; // \r\n 142 | else 143 | */ 144 | if (pos1 < pos2) pos = pos1; else pos = pos2; 145 | } else { 146 | if (pos1 == -1) pos = pos2; 147 | else 148 | if (pos2 == -1) pos = pos1; 149 | } 150 | 151 | return pos; 152 | } 153 | 154 | /*! 155 | Do some clean up, and be sure that all output has been read. 156 | */ 157 | void MyProcess::procFinished() { 158 | qDebug("MyProcess::procFinished"); 159 | 160 | #if !USE_TEMP_FILE 161 | qDebug("MyProcess::procFinished: Bytes available: %ld", bytesAvailable()); 162 | if ( bytesAvailable() > 0 ) readStdOut(); 163 | #else 164 | timer.stop(); 165 | 166 | qDebug("MyProcess::procFinished: Bytes available: %ld", temp_file.bytesAvailable()); 167 | if ( temp_file.bytesAvailable() > 0 ) readTmpFile(); 168 | qDebug("MyProcess::procFinished: Bytes available: %ld", temp_file.bytesAvailable()); 169 | 170 | temp_file.close(); 171 | #endif 172 | } 173 | 174 | QStringList MyProcess::splitArguments(const QString & args) { 175 | qDebug("MyProcess::splitArguments: '%s'", args.toUtf8().constData()); 176 | 177 | QStringList l; 178 | 179 | bool opened_quote = false; 180 | int init_pos = 0; 181 | for (int n = 0; n < args.length(); n++) { 182 | if ((args[n] == QChar(' ')) && (!opened_quote)) { 183 | l.append(args.mid(init_pos, n - init_pos)); 184 | init_pos = n+1; 185 | } 186 | else 187 | if (args[n] == QChar('\"')) opened_quote = !opened_quote; 188 | 189 | if (n == args.length()-1) { 190 | l.append(args.mid(init_pos, (n - init_pos)+1)); 191 | } 192 | } 193 | 194 | for (int n = 0; n < l.count(); n++) { 195 | qDebug("MyProcess::splitArguments: arg: %d '%s'", n, l[n].toUtf8().constData()); 196 | } 197 | 198 | return l; 199 | } 200 | 201 | 202 | -------------------------------------------------------------------------------- /myprocess.h: -------------------------------------------------------------------------------- 1 | /* smplayer, GUI front-end for mplayer. 2 | Copyright (C) 2006-2009 Ricardo Villalba 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | */ 18 | 19 | #ifndef _MY_PROCESS_H_ 20 | #define _MY_PROCESS_H_ 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | //! MyProcess is a specialized QProcess designed to properly work with mplayer. 27 | 28 | /*! 29 | It can split the mplayer status line into lines. 30 | It also provides some Qt 3 like functions like addArgument(). 31 | 32 | There are two working modes, controlled by the USE_TEMP_FILE define. 33 | If USE_TEMP_FILE is 1 it will send the output of mplayer to a temporary 34 | file, and then it will be read from it. Otherwise it will read from 35 | standard ouput as usual. 36 | */ 37 | 38 | class MyProcess : public QProcess 39 | { 40 | Q_OBJECT 41 | 42 | public: 43 | MyProcess ( QObject * parent = 0 ); 44 | 45 | void addArgument(const QString & a); //!< Add an argument 46 | 47 | void clearArguments(); //!< Clear the list of arguments 48 | QStringList arguments(); //!< Return the list of arguments 49 | 50 | void start(); //!< Start the process 51 | bool isRunning(); //!< Return true if the process is running 52 | 53 | static QStringList splitArguments(const QString & args); 54 | 55 | signals: 56 | //! Emitted when there's a line available 57 | void lineAvailable(QByteArray ba); 58 | 59 | protected slots: 60 | void readStdOut(); //!< Called for reading from standard output 61 | void readTmpFile(); //!< Called for reading from the temp file 62 | void procFinished(); //!< Called when the process has finished 63 | 64 | protected: 65 | //! Return true if it's possible to read an entire line. 66 | /*! @param from specifies the position to begin. */ 67 | int canReadLine(const QByteArray & ba, int from = 0); 68 | //! Called from readStdOut() and readTmpFile() to do all the work 69 | void genericRead(QByteArray buffer); 70 | 71 | private: 72 | QString program; 73 | QStringList arg; 74 | 75 | QByteArray remaining_output; 76 | 77 | QTemporaryFile temp_file; 78 | QTimer timer; 79 | }; 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /neuralstyler: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rupeshs/neuralstyler/ff4986fc77f4be6a0a0b10e4a9dc60e6057d0487/neuralstyler -------------------------------------------------------------------------------- /neuralstyler-help/help/docs/hstyle.md: -------------------------------------------------------------------------------- 1 | #Basics 2 | 3 | Using NeuralStyle You can style video files,photos and Gifs. 4 | 5 | Media | Input format | Output format 6 | ------------ | ------------- | ------------ 7 | Video | All major video formats | MP4 8 | Photos | All major image formats | jpeg 9 | Gif| --|gif 10 | 11 | #How to Style 12 | 13 | 14 | Select the video you want to style,select style,resolution etc then press the "Create Artistic Style" button 15 | 16 | ![Screenshot](img/neuralstyler1.jpg) 17 | 18 | Wait for some time it will style your video. 19 | Styling speed depends on 20 | 21 | * CPU clock speed 22 | * Resolution (lower the resolution faster will be the styling) 23 | * Amount of RAM available(High resolution images/video needs more RAM) 24 | 25 | For photos you can adjut style strength after styling 26 | 27 | ![Screenshot](img/neuralstyler-save.jpg) 28 | 29 | ## How to view styled videos/photos 30 | 31 | To open output folder you can use "Open Styled Videos" button 32 | 33 | ##How to download new style 34 | 35 | New styles will be avilable [here](http://neuralstyler.com/styles.html) -------------------------------------------------------------------------------- /neuralstyler-help/help/docs/img/neuralstyler-save.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rupeshs/neuralstyler/ff4986fc77f4be6a0a0b10e4a9dc60e6057d0487/neuralstyler-help/help/docs/img/neuralstyler-save.jpg -------------------------------------------------------------------------------- /neuralstyler-help/help/docs/img/neuralstyler1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rupeshs/neuralstyler/ff4986fc77f4be6a0a0b10e4a9dc60e6057d0487/neuralstyler-help/help/docs/img/neuralstyler1.jpg -------------------------------------------------------------------------------- /neuralstyler-help/help/docs/img/styles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rupeshs/neuralstyler/ff4986fc77f4be6a0a0b10e4a9dc60e6057d0487/neuralstyler-help/help/docs/img/styles.png -------------------------------------------------------------------------------- /neuralstyler-help/help/docs/img/videosection.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rupeshs/neuralstyler/ff4986fc77f4be6a0a0b10e4a9dc60e6057d0487/neuralstyler-help/help/docs/img/videosection.PNG -------------------------------------------------------------------------------- /neuralstyler-help/help/docs/index.md: -------------------------------------------------------------------------------- 1 | # NeuralStyler 2 | 3 | Turn Your Videos/Photos/GIF into Art 4 | 5 | NeuralStyler Artificial Intelligence converts your videos into art works by using styles of famous artists: Van Gogh,Wassily Kandinsky,Georges Seurat etc 6 | 7 | * Style videos,gif animation and photos 8 | * No need to upload videos (Offline processing) 9 | * Faster AI styling algorithm 10 | * Extensible styling system(Plugin) 11 | * style sterngth 12 | * Style video section 13 | -------------------------------------------------------------------------------- /neuralstyler-help/help/docs/options.md: -------------------------------------------------------------------------------- 1 | NeuralStyler has following settings 2 | 3 | * Styles 4 | * Resolution 5 | * Keep aspect ratio 6 | * No scaling 7 | * Style strenth 8 | * Video selection 9 | 10 | ## Styles 11 | 12 | You can select wide variety of styles for artistic styling. 13 | 14 | ![Screenshot](img/styles.png) 15 | 16 | Styles uses plugin like system for more details styles help page. 17 | 18 | ## Resolution 19 | 20 | Video/Image output resolution 21 | From version 2.0 it is possible to give custom size 22 | 23 | ## Keep Aspect Ratio 24 | 25 | If this is enabled then output will keep its aspect ratio. 26 | 27 | ## No scaling 28 | 29 | Completly disable scaling. 30 | Beware if your input image/video having high resoltion then it will take longer time to process and the amount of RAM required will be high. 31 | 32 | ## Style strength 33 | 34 | Intensity of styling can be adjusted from 0 to 100% 35 | 36 | ## Video selection 37 | 38 | You can select the section of video for styling 39 | 40 | ![Screenshot](img/videosection.PNG) -------------------------------------------------------------------------------- /neuralstyler-help/help/docs/styles.md: -------------------------------------------------------------------------------- 1 | 2 | ## How to install style 3 | 4 | Simply download the zip file from [styles page](http://neuralstyler.com/styles.html) and extract it you will get two files 5 | 6 | * style_name.model 7 | * style_name-style.jpg 8 | 9 | copy these two files to the styles folder and run NeuralStyler. 10 | 11 | ## Create your own styles 12 | 13 | [Please read the neural network training instructions](https://github.com/yusuketomoto/chainer-fast-neuralstyle#train) 14 | 15 | Dependencies 16 | 17 | * [Chainer](http://chainer.org/) 18 | * [Microsoft COCO dataset](http://mscoco.org/dataset/#download) 19 | 20 | ``` 21 | python train.py -s (style_image_path) -d (training_dataset_path) -g (use_gpu ? gpu_id : -1) 22 | ``` -------------------------------------------------------------------------------- /neuralstyler-help/help/mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: Help 2 | pages: 3 | - Introduction: index.md 4 | - Settings: options.md 5 | - Styles: styles.md 6 | - How to style : hstyle.md 7 | theme: readthedocs -------------------------------------------------------------------------------- /neuralstyler-logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rupeshs/neuralstyler/ff4986fc77f4be6a0a0b10e4a9dc60e6057d0487/neuralstyler-logo.jpg -------------------------------------------------------------------------------- /neuralstyler.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | neuralstyler-logo.jpg 4 | images/fileopen.png 5 | images/pause.png 6 | images/paint.png 7 | images/filesave .png 8 | images/wm.png 9 | images/paint-cancel.png 10 | images/preview.png 11 | 12 | 13 | -------------------------------------------------------------------------------- /neuralstyler.rc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | VS_VERSION_INFO VERSIONINFO 5 | FILEVERSION VER_FILEVERSION 6 | PRODUCTVERSION VER_PRODUCTVERSION 7 | FILEOS VOS_NT_WINDOWS32 8 | FILETYPE VFT_APP 9 | { 10 | BLOCK "StringFileInfo" 11 | { 12 | BLOCK "000004b0" 13 | { 14 | VALUE "CompanyName", VER_COMPANYNAME_STR 15 | VALUE "FileDescription", VER_FILEDESCRIPTION_STR 16 | VALUE "FileVersion", VER_FILEVERSION_STR 17 | VALUE "InternalName", VER_INTERNALNAME_STR 18 | VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR 19 | VALUE "OriginalFilename", VER_ORIGINALFILENAME_STR 20 | VALUE "ProductName", VER_PRODUCTNAME_STR 21 | VALUE "ProductVersion", VER_PRODUCTVERSION_STR 22 | } 23 | } 24 | BLOCK "VarFileInfo" 25 | { 26 | VALUE "Translation", 0, 0x04b0 27 | } 28 | } 29 | 30 | 31 | IDI_ICON1 ICON DISCARDABLE "NeuralStyler.ico" -------------------------------------------------------------------------------- /neuralstylerwindow.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | NeuralStyler,Artistic style for your videos/photos 3 | Copyright(C) 2016 Rupesh Sreeraman 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | You should have received a copy of the GNU General Public License 13 | along with this program; if not, write to the Free Software 14 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 15 | */ 16 | 17 | #include "neuralstylerwindow.h" 18 | #include "ui_neuralstylerwindow.h" 19 | 20 | NeuralStylerWindow::NeuralStylerWindow(QWidget *parent) : 21 | QMainWindow(parent), 22 | ui(new Ui::NeuralStylerWindow) 23 | { 24 | 25 | ui->setupUi(this); 26 | // QCoreApplication::addLibraryPath(qApp->applicationDirPath()+QDir::separator()+"platforms"); 27 | paths=new Paths(qApp->applicationDirPath()); 28 | QDir styleDir(paths->getStylePath()); 29 | QStringList filters; 30 | QStringList lstStyles; 31 | ui->checkBoxKeepAspectRatio->setChecked(true); 32 | 33 | filters<<"*.model"; 34 | styleDir.setNameFilters(filters); 35 | lstStyles.clear(); 36 | lstStyles=styleDir.entryList(); 37 | QStringList lstStyleNames; 38 | for (int i = 0; i < lstStyles.count(); i++) { 39 | QFileInfo fileInfo(QFile(paths->getStylePath()+lstStyles.at(i))); 40 | lstStyleNames<comboBoxStyles->addItems(lstStyleNames); 43 | timer = new QTimer(this); 44 | connect(timer, SIGNAL(timeout()), this, SLOT(update())); 45 | 46 | // m_mpv = new MpvWidget(this); 47 | #ifdef Q_OS_WIN 48 | mPath= qApp->applicationDirPath()+ "/mplayer/mplayer.exe"; 49 | #endif 50 | #ifdef Q_OS_LINUX 51 | mPath="/usr/bin/mplayer"; 52 | # endif 53 | #ifdef Q_OS_OPENBSD 54 | mPath="/usr/local/bin/mplayer"; 55 | # endif 56 | if(!QFile(mPath).exists()){ 57 | QMessageBox::critical(this,qApp->applicationName(),"Oops..MPlayer not found,Video trimming will not work...Please install MPlayer"); 58 | } 59 | 60 | qDebug()<setMplayerPath(mPath); 63 | connect(mp,SIGNAL(gotduration(float)),this,SLOT(setSliderRange(float))); 64 | connect(ui->frameSlider, SIGNAL(lowerValueChanged(int)), SLOT(seek(int))); 65 | connect(ui->frameSlider, SIGNAL(upperValueChanged(int)), SLOT(seek(int))); 66 | 67 | mplayerVideo=new QLabel(this); 68 | mplayerVideo->setGeometry(0,0,261,181); 69 | mplayerVideo->setMinimumWidth(261); 70 | 71 | 72 | mplayerVideo->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Expanding); 73 | mplayerVideo->setStyleSheet("background-color:black;"); 74 | mp->setVideoWin(mplayerVideo->winId()); 75 | #ifdef Q_OS_LINUX 76 | mp->setScaling(261,181); 77 | #endif 78 | 79 | QVBoxLayout *vl = new QVBoxLayout(); 80 | 81 | videoTimeLabel = new QLabel("00:00:00"); 82 | videoStatusLabel = new QLabel("Select video section"); 83 | 84 | vl->addWidget(mplayerVideo); 85 | vl->addWidget(ui->frameSlider); 86 | vl->addWidget(videoStatusLabel); 87 | vl->addWidget(videoTimeLabel); 88 | ui->groupBox_2->setLayout(vl); 89 | 90 | ui->frameSlider->setHandleMovementMode(QxtSpanSlider::NoCrossing); 91 | ui->pushButtonPause->setEnabled(false); 92 | ui->pushButtonViewFrame->setEnabled(false); 93 | 94 | //Check settings exists 95 | if(!QFile(qApp->applicationDirPath()+"/neuralstyler.ini").exists()){ 96 | qDebug()<<"Settings not found!"; 97 | paths->setStyledVideoPath(qApp->applicationDirPath()+"/styledvideo"); 98 | ui->lineEditSavePath->setText( paths->getStyledVideoPath()); 99 | 100 | } 101 | 102 | settings=new QSettings(qApp->applicationDirPath()+"/neuralstyler.ini",QSettings::IniFormat,this); 103 | 104 | 105 | qDebug()<value("Main/destination","").toString(); 106 | if(settings->value("Main/destination","").toString().compare("")==0){ 107 | 108 | settings->beginGroup("Main"); 109 | settings->setValue("destination", paths->getStyledVideoPath()); 110 | settings->endGroup(); 111 | 112 | 113 | } 114 | else{ 115 | ui->lineEditSavePath->setText(settings->value("Main/destination",paths->getStyledVideoPath()).toString()); 116 | paths->setStyledVideoPath(ui->lineEditSavePath->text()); 117 | } 118 | 119 | ui->groupBox_2->setEnabled(false); 120 | ui->groupBoxRes->setVisible(false); 121 | 122 | bitSettingsFirstRun=new QBitArray(2,true); 123 | //bit 0 first run 124 | //bit 1 load trim slider 125 | engineState(false); 126 | setAcceptDrops(true); 127 | 128 | 129 | 130 | } 131 | 132 | NeuralStylerWindow::~NeuralStylerWindow() 133 | { 134 | delete ui; 135 | } 136 | 137 | void NeuralStylerWindow::on_pushButonBrowseFile_clicked() 138 | { 139 | 140 | QString fileName = QFileDialog::getOpenFileName(this, 141 | tr("Open video"), "", tr("videoFiles (*.*)")); 142 | 143 | 144 | if (fileName.isEmpty()) 145 | return; 146 | ui->lineEditFilePath->setText(fileName); 147 | initVideoTrim(); 148 | 149 | } 150 | 151 | void NeuralStylerWindow::on_pushButtonProcess_clicked() 152 | { 153 | 154 | if (ui->pushButtonProcess->text().compare("Cancel Neural Styling")==0){ 155 | 156 | QMessageBox::StandardButton reply; 157 | reply = QMessageBox::question(this, "NeuralStyler", "Do you want to stop styling ?", 158 | QMessageBox::Yes|QMessageBox::No); 159 | if (reply == QMessageBox::Yes) { 160 | engineState(true); 161 | if (ffmpeg){ 162 | ffmpeg->write("q\n"); 163 | ffmpeg->waitForBytesWritten(1000); 164 | } 165 | qApp->exit( NeuralStylerWindow::EXIT_CODE_REBOOT ); 166 | } 167 | else{ 168 | return; 169 | } 170 | } 171 | 172 | // qApp->exit( NeuralStylerWindow::EXIT_CODE_REBOOT ); 173 | tElapsed.start(); 174 | timer->start(1000); 175 | 176 | if (!QFile(ui->lineEditFilePath->text()).exists()){ 177 | QMessageBox::critical(this,qApp->applicationName(),"Please provide a valid file!"); 178 | return; 179 | } 180 | if(ui->comboBoxResolution->currentText().compare("Custom")==0){ 181 | 182 | if (ui->lineEditWidth->text().toInt()>0&&ui->lineEditHeight->text().toInt()) 183 | { 184 | //process 185 | }else{ 186 | QMessageBox::critical(this,qApp->applicationName(),"Please provide valid resolution(Width x Height)"); 187 | return; 188 | 189 | } 190 | } 191 | //ui->pushButtonProcess->setText("Cancel"); 192 | ui->progressBarOverall->setValue(0); 193 | ui->groupBox->setDisabled(true); 194 | ui->groupBox_2->setDisabled(true); 195 | 196 | //Clean folders 197 | QDir(paths->getAudioPath()).removeRecursively(); 198 | QDir(paths->getFramePath()).removeRecursively(); 199 | QDir(paths->getStyledFramePath()).removeRecursively(); 200 | 201 | paths->ensureFramePath(); 202 | paths->ensureAudioPath(); 203 | paths->ensureStyledFramePath(); 204 | paths->ensureStyledVideoPath(); 205 | engineState(true); 206 | getFramePerSec(); 207 | ui->pushButtonProcess->setText("Cancel Neural Styling"); 208 | ui->pushButtonProcess->setIcon(QPixmap(":/images/paint-cancel.png")); 209 | 210 | } 211 | void NeuralStylerWindow::fpsStarted() 212 | { 213 | qDebug()<<"Get fps"; 214 | 215 | } 216 | void NeuralStylerWindow::fpsCompleted(int ec) 217 | { 218 | ui->labelStatus->setText("Extracting frames..."); 219 | strFramesPerSec=ffmpeg->getFps(); 220 | qDebug()<<"fps ok "<getDuration(); 222 | 223 | QTime totTime=QTime::fromString(strDuration.trimmed(),"hh:mm:ss.z"); 224 | // qDebug()<<"Video Duration :"<< strDuration; 225 | qDebug()<<"Video Duration :"<progressBarFrame->setValue(0); 234 | ffmpeg->deleteLater(); 235 | 236 | ui->progressBarOverall->setValue(16); 237 | extractFrames(); 238 | 239 | } 240 | 241 | void NeuralStylerWindow::getFramePerSec() 242 | { 243 | strFramesPerSec=""; 244 | ffmpeg=new FfmpegProcess(); 245 | connect(ffmpeg,SIGNAL(started()),this,SLOT(fpsStarted())); 246 | connect(ffmpeg,SIGNAL(finished(int)),this,SLOT(fpsCompleted(int))); 247 | 248 | QStringList arguments; 249 | arguments << "-i" << ui->lineEditFilePath->text(); 250 | 251 | ffmpeg->setArguments(arguments); 252 | ffmpeg->startFfmpeg(); 253 | } 254 | void NeuralStylerWindow::extractFrames() 255 | { 256 | paths->ensureFramePath(); 257 | ui->progressBarOverall->setValue(33); 258 | //./ffmpeg -i strip_jp.mkv -vf scale=320:240 frames/frame%05d.jpg 259 | ffmpeg=new FfmpegProcess(); 260 | connect(ffmpeg,SIGNAL(started()),this,SLOT(frameExtratorStarted())); 261 | connect(ffmpeg,SIGNAL(finished(int)),this,SLOT(frameExtratorCompleted(int))); 262 | connect(ffmpeg,SIGNAL(gotFrame(QString)),this,SLOT(gotFrame(QString))); 263 | QStringList arguments; 264 | QString strResolution=ui->comboBoxResolution->currentText(); 265 | 266 | if (strResolution.compare("Custom")==0) { 267 | strResolution=ui->lineEditWidth->text()+"x"+ui->lineEditHeight->text(); 268 | } 269 | 270 | QString strWidth; 271 | QString strHeight; 272 | 273 | if (rx_width.indexIn(strResolution)>-1) { 274 | 275 | strWidth=rx_width.cap(1); 276 | } 277 | if (rx_height.indexIn(strResolution)>-1) { 278 | 279 | strHeight=rx_height.cap(1); 280 | } 281 | 282 | //<<"-ss"<frameSlider->lowerValue()); 284 | QString strStyleDur=QString::number(ui->frameSlider->upperValue()-ui->frameSlider->lowerValue()); 285 | 286 | //input 287 | arguments << "-i" << ui->lineEditFilePath->text() ; 288 | 289 | //trim video 290 | if (!isImageOrGif()) 291 | arguments<<"-ss"<checkBoxNoScale->isChecked()){ 295 | 296 | //aspect ratio 297 | if(ui->checkBoxKeepAspectRatio->isChecked()) 298 | arguments <<"-vf"<<"scale="+strWidth+":"+QString::number(-1)+":flags=lanczos"; 299 | else 300 | arguments<<"-vf"<<"scale="+strResolution.replace("x",":")+":flags=lanczos"; 301 | } 302 | 303 | //output 304 | arguments <<"-qscale:v"<<"2"<getFramePath()+"frame%05d.jpg"; 305 | 306 | ffmpeg->setArguments(arguments); 307 | ffmpeg->startFfmpeg(); 308 | 309 | } 310 | void NeuralStylerWindow::frameExtratorStarted() 311 | { 312 | qDebug()<<"Extract frames"; 313 | 314 | } 315 | void NeuralStylerWindow::frameExtratorCompleted(int ec) 316 | { 317 | qDebug()<<"Frame extraction ok"; 318 | //delete ffmpeg; 319 | ffmpeg->deleteLater(); 320 | ui->progressBarOverall->setValue(49); 321 | ui->progressBarFrame->setValue(100); 322 | ui->labelStatus->setText("Extracting audio.."); 323 | extractAudio(); 324 | 325 | } 326 | void NeuralStylerWindow::extractAudio() 327 | { 328 | ffmpeg=new FfmpegProcess(); 329 | connect(ffmpeg,SIGNAL(started()),this,SLOT(audioExtratorStarted())); 330 | connect(ffmpeg,SIGNAL(finished(int)),this,SLOT(audioExtratorCompleted(int))); 331 | 332 | QStringList arguments; 333 | QString strStartPos=QString::number(ui->frameSlider->lowerValue()); 334 | QString strStyleDur=QString::number(ui->frameSlider->upperValue()-ui->frameSlider->lowerValue()); 335 | 336 | 337 | arguments << "-i" << ui->lineEditFilePath->text()<<"-ss"<getAudioPath()+"audio.wav"; 338 | ffmpeg->setArguments(arguments); 339 | ffmpeg->startFfmpeg(); 340 | 341 | } 342 | 343 | void NeuralStylerWindow::audioExtratorStarted() 344 | { 345 | qDebug()<<"Extract audio"; 346 | 347 | } 348 | void NeuralStylerWindow::audioExtratorCompleted(int ec) 349 | { 350 | qDebug()<<"Audio extraction ok"; 351 | ui->progressBarOverall->setValue(65); 352 | //delete ffmpeg; 353 | ffmpeg->deleteLater(); 354 | ui->labelStatus->setText("Styling frames.."); 355 | paths->ensureStyledFramePath(); 356 | styleFrames(); 357 | 358 | } 359 | 360 | void NeuralStylerWindow::styleFrames() 361 | { 362 | 363 | //ui->pushButtonViewFrame->setEnabled(true); 364 | QDir framesDir(paths->getFramePath()); 365 | 366 | QStringList filters; 367 | filters<<"*.jpg"; 368 | framesDir.setNameFilters(filters); 369 | lstFrames.clear(); 370 | lstFrames=framesDir.entryList(); 371 | //qDebug()<0) 376 | chainerProcess(); 377 | else 378 | { 379 | QMessageBox::critical(this,qApp->applicationName(),"Styling failed! Invalid file."); 380 | finishStyling(); 381 | 382 | } 383 | if(lstFrames.size()>1){ 384 | ui->pushButtonViewFrame->setEnabled(true); 385 | ui->pushButtonPause->setEnabled(true); 386 | } 387 | 388 | } 389 | void NeuralStylerWindow::fastNeuralStyleStarted() 390 | { 391 | qDebug()<<"Style start"; 392 | 393 | } 394 | void NeuralStylerWindow::fastNeuralStyleCompleted(int ec) 395 | { 396 | 397 | if (fastNeuralStyle->getProcessingTime().isEmpty()){ 398 | qDebug()<<"Style Frame failed"; 399 | QMessageBox::critical(this,qApp->applicationName(),"Memory Error:Insufficient RAM to process this resolution,change resolution"); 400 | timer->stop(); 401 | fastNeuralStyle->deleteLater(); 402 | qApp->exit( NeuralStylerWindow::EXIT_CODE_REBOOT ); 403 | 404 | return; 405 | 406 | } 407 | else 408 | { 409 | QImage top(paths->getStyledFramePath()+lstFrames.at(processingFrameCount-1)); 410 | QImage bot(paths->getFramePath()+lstFrames.at(processingFrameCount-1)); 411 | QPixmap combined(bot.size()); 412 | QPainter p(&combined); 413 | QImage wm(":/images/wm.png"); 414 | 415 | p.drawImage(QPoint(0, 0), bot); // drawn as-is 416 | p.setOpacity(ui->sliderStyleStrength->value()/100.0); 417 | p.drawImage(QPoint(0, 0), top); 418 | p.end(); 419 | 420 | 421 | //Draw water mark 422 | QPainter p2(&combined); 423 | 424 | /* 425 | +---------------------------+ 426 | | 5 | 427 | |<----5------>wm<----5----->| 428 | | 5 | 429 | +---------------------------+ 430 | 431 | Rect width = wm.width+10 432 | Rect height =wm.height+10 433 | Rect x =imgwidth-width 434 | Rect y =img height-height 435 | */ 436 | int pad=8; 437 | int rectWidth = wm.width()+(pad*2); 438 | int rectHeight = wm.height()+(pad*2); 439 | int rectLeft = bot.width()-rectWidth; 440 | int rectTop = bot.height()-rectHeight; 441 | 442 | /* 443 | Water mark image 444 | Point x =rectLeft+pad 445 | Point y =rectTop+pad */ 446 | 447 | int wmLeft = rectLeft+pad; 448 | int wmTop = rectTop+pad; 449 | 450 | 451 | p2.fillRect(QRect(rectLeft,rectTop,rectWidth,rectHeight), QBrush(QColor(0, 0, 0, 128))); 452 | p2.drawImage(QPoint(wmLeft, wmTop), wm); 453 | p2.end(); 454 | combined.save(paths->getStyledFramePath()+"ns"+lstFrames.at(processingFrameCount-1)); 455 | 456 | // ui->labelStyleImage->setPixmap(QPixmap(paths->getStyledFramePath()+"ns"+lstFrames.at(processingFrameCount-1)).scaled(QSize(120,90),Qt::KeepAspectRatio,Qt::FastTransformation)); 457 | // ui->labelStyleImage->setEnabled(true); 458 | emit updatePreviewFrame(paths->getStyledFramePath()+"ns"+lstFrames.at(processingFrameCount-1)); 459 | qDebug()<<"Style Frame ok"; 460 | } 461 | 462 | //delete fastNeuralStyle; 463 | fastNeuralStyle->deleteLater(); 464 | ui->progressBarOverall->setValue(81); 465 | 466 | if (ui->pushButtonPause->text().compare("Pause")==0) 467 | chainerProcess(); 468 | 469 | } 470 | 471 | void NeuralStylerWindow::chainerProcess() 472 | { 473 | 474 | processingFrameCount++; 475 | if (processingFrameCount<=lstFrames.count()){ 476 | 477 | ui->labelStatus->setText("Artistic styling frame "+QString::number(processingFrameCount)+" of "+QString::number(lstFrames.count())); 478 | float per=(float)processingFrameCount/(float)lstFrames.count(); 479 | ui->progressBarFrame->setValue(per*100); 480 | 481 | fastNeuralStyle=new StyleChainer(); 482 | fastNeuralStyle->setAppPath(paths->getAppPath()); 483 | connect(fastNeuralStyle,SIGNAL(started()),this,SLOT(fastNeuralStyleStarted())); 484 | connect(fastNeuralStyle,SIGNAL(finished(int)),this,SLOT(fastNeuralStyleCompleted(int))); 485 | QStringList arguments; 486 | arguments << paths->getAppPath()+"env/generate.py" << paths->getFramePath()+lstFrames.at(processingFrameCount-1) 487 | <<"-m"<getStylePath()+ui->comboBoxStyles->currentText()+".model"<< 488 | "-o"<getStyledFramePath()+lstFrames.at(processingFrameCount-1); 489 | fastNeuralStyle->setArguments(arguments); 490 | fastNeuralStyle->sytleIt(); 491 | } else { 492 | 493 | createStyledVideo(); 494 | 495 | } 496 | } 497 | void NeuralStylerWindow::createStyledVideo() 498 | { 499 | ui->pushButtonPause->setText("Pause"); 500 | ui->pushButtonPause->setEnabled(false); 501 | ui->pushButtonViewFrame->setEnabled(false); 502 | 503 | //./ffmpeg -framerate 25 -i out/frames/frame%05d.jpg -i jp_audio.wav -c:a aac -strict -2 -y gif/testgv.mp4 504 | 505 | ffmpeg=new FfmpegProcess(); 506 | connect(ffmpeg,SIGNAL(started()),this,SLOT(styledVideoStarted())); 507 | connect(ffmpeg,SIGNAL(finished(int)),this,SLOT(styledVideoCompleted(int))); 508 | 509 | QStringList arguments; 510 | 511 | QFileInfo fileInfo(QFile(ui->lineEditFilePath->text())); 512 | //Handle Video ->MP4 513 | if(fileInfo.suffix().toLower().compare("gif")!=0) { 514 | 515 | if (QFile(paths->getAudioPath()+"audio.wav").exists()&& QFile(paths->getAudioPath()+"audio.wav").size()>0&&strFramesPerSec.compare("")!=0){ 516 | 517 | //video 518 | arguments << "-framerate" << strFramesPerSec 519 | <<"-i"<getStyledFramePath()+"nsframe%05d.jpg" 520 | <<"-i"<< paths->getAudioPath()+"audio.wav" 521 | <<"-c:a"<<"aac"<< "-strict"<<"-2" 522 | <<"-y"<getStyledVideoPath()+fileInfo.baseName()+"_"+ui->comboBoxStyles->currentText()+".mp4"; 523 | 524 | } else { 525 | 526 | //Video with No audio 527 | QDir frameDir(paths->getStyledFramePath()); 528 | QStringList filters; 529 | QStringList lstStyledFrames; 530 | filters<<"*.jpg"; 531 | QFileInfo fileInfo(QFile(ui->lineEditFilePath->text())); 532 | 533 | frameDir.setNameFilters(filters); 534 | lstStyledFrames.clear(); 535 | lstStyledFrames=frameDir.entryList(); 536 | 537 | //Can be image 538 | if (lstStyledFrames.count()==2) { // Image 539 | 540 | 541 | // Just copy 542 | if (QFile::exists(paths->getStyledVideoPath()+fileInfo.baseName()+"_"+ui->comboBoxStyles->currentText()+".jpg")) 543 | QFile::remove(paths->getStyledVideoPath()+fileInfo.baseName()+"_"+ui->comboBoxStyles->currentText()+".jpg"); 544 | QFile(paths->getStyledFramePath()+"frame00001.jpg").copy(paths->getStyledVideoPath()+fileInfo.baseName()+"_"+ui->comboBoxStyles->currentText()+".jpg"); 545 | 546 | styleIntensityDlg=new StyleIntensityDialog(this,paths->getFramePath()+lstFrames.at(0), 547 | paths->getStyledFramePath()+lstFrames.at(0), 548 | paths->getStyledVideoPath()+fileInfo.baseName()+"_"+ui->comboBoxStyles->currentText()+".jpg"); 549 | styleIntensityDlg->show(); 550 | 551 | finishStyling(); 552 | ffmpeg->deleteLater(); 553 | return ; 554 | 555 | } else { 556 | //Video with out audio 557 | arguments << "-framerate" << strFramesPerSec 558 | <<"-i"<getStyledFramePath()+"nsframe%05d.jpg" 559 | <<"-y"<getStyledVideoPath()+fileInfo.baseName()+"_"+ui->comboBoxStyles->currentText()+".mp4"; 560 | 561 | } 562 | 563 | 564 | } 565 | 566 | } else { 567 | 568 | //GIF 569 | arguments << "-framerate" << strFramesPerSec 570 | <<"-i"<getStyledFramePath()+"nsframe%05d.jpg" 571 | <<"-y"<getStyledVideoPath()+fileInfo.baseName()+"_"+ui->comboBoxStyles->currentText()+".gif"; 572 | 573 | } 574 | 575 | 576 | ffmpeg->setArguments(arguments); 577 | ffmpeg->startFfmpeg(); 578 | 579 | 580 | } 581 | 582 | void NeuralStylerWindow::styledVideoStarted() 583 | { 584 | qDebug()<<"creating styled video"; 585 | ui->labelStatus->setText("Creating artwork..."); 586 | 587 | } 588 | void NeuralStylerWindow::styledVideoCompleted(int ec) 589 | { 590 | qDebug()<<"Styled video created"; 591 | 592 | ffmpeg->deleteLater(); 593 | finishStyling(); 594 | } 595 | 596 | void NeuralStylerWindow::gotFrame(QString fnum) 597 | { 598 | int64_t fnumer=fnum.toLongLong(); 599 | 600 | if(frameCount>0&&fnum>0) 601 | { 602 | 603 | float per=(float)fnumer/(float)frameCount; 604 | qDebug()<<"frame extract:"<progressBarFrame->setValue(per*100); 607 | } 608 | } 609 | 610 | void NeuralStylerWindow::on_comboBoxStyles_currentIndexChanged(const QString &arg1) 611 | { 612 | qDebug()<getStylePath()+arg1+"-style.jpg"); 614 | if (pixmap.height()>0){ 615 | ui->labelStyleImage->setPixmap(pixmap); 616 | } 617 | else{ 618 | ui->labelStyleImage->setText("No preview"); 619 | } 620 | } 621 | 622 | void NeuralStylerWindow::on_pushButtonOpenOutput_clicked() 623 | { 624 | 625 | QDesktopServices::openUrl(QUrl::fromLocalFile(paths->getStyledVideoPath())); 626 | } 627 | 628 | void NeuralStylerWindow::on_actionAbout_triggered() 629 | { 630 | aboutDlg=new AboutDialog(this); 631 | aboutDlg->show(); 632 | } 633 | void NeuralStylerWindow::update() 634 | { 635 | //qDebug()<labelElapsedTime->setText( QTime(0,0,0,0).addMSecs(tElapsed.elapsed()).toString("hh:mm:ss")); 637 | } 638 | 639 | void NeuralStylerWindow::finishStyling() 640 | { 641 | ui->pushButtonProcess->setText("Create Artistic Style"); 642 | ui->pushButtonProcess->setIcon(QPixmap(":/images/paint.png")); 643 | 644 | ui->labelStatus->setText("Styling completed."); 645 | ui->groupBox->setDisabled(false); 646 | ui->groupBox_2->setDisabled(false); 647 | timer->stop(); 648 | ui->progressBarOverall->setValue(100); 649 | ui->progressBarFrame->setValue(100); 650 | if (lstFrames.count()>0){ 651 | 652 | if (isImageOrGif()){ 653 | if (isGif()) 654 | QMessageBox::information(this,"NeuralStyler","Artistic gif created."); 655 | else 656 | QMessageBox::information(this,"NeuralStyler","Artistic image created."); 657 | ui->groupBox_2->setEnabled(false); 658 | } 659 | else{ 660 | QMessageBox::information(this,"NeuralStyler","Artistic video created."); 661 | } 662 | } 663 | //delete ffmpeg; 664 | } 665 | void NeuralStylerWindow::seek(int pos) 666 | { 667 | 668 | 669 | mp->command("pausing seek "+QString::number(pos)+" 2"); 670 | // qDebug()<frameSlider->lowerValue())+"="+QString::number(ui->frameSlider->upperValue()); 671 | if (ui->frameSlider->lowerValue()frameSlider->upperValue()){ 672 | 673 | QTime posStart(0,0,0); 674 | QTime posEnd(0,0,0); 675 | QTime styleDur(0,0,0); 676 | int styleDuration=ui->frameSlider->upperValue()-ui->frameSlider->lowerValue(); 677 | videoTimeLabel->setText("Length : "+styleDur.addSecs(styleDuration).toString("hh:mm:ss")); 678 | QString strVideoStatus="Style video from "+posStart.addSecs(ui->frameSlider->lowerValue()).toString("hh:mm:ss")+" to "+posEnd.addSecs(ui->frameSlider->upperValue()).toString("hh:mm:ss")+""; 679 | videoStatusLabel->setText(strVideoStatus); 680 | } 681 | else{ 682 | videoStatusLabel->setText("Invalid Duration!"); 683 | } 684 | } 685 | void NeuralStylerWindow::setSliderRange(float dur) 686 | { 687 | int duration=dur; 688 | ui->frameSlider->setRange(0, duration); 689 | ui->frameSlider->setLowerValue(0); 690 | ui->frameSlider->setUpperValue(duration); 691 | QTime tmDuration(0,0,0); 692 | QString strVideoDuration="Length :"+tmDuration.addSecs(duration).toString("hh:mm:ss"); 693 | videoTimeLabel->setText(strVideoDuration); 694 | if(bitSettingsFirstRun->testBit(1)){ 695 | ui->frameSlider->setUpperPosition(settings->value("State/trimup",1).toInt()); 696 | ui->frameSlider->setLowerPosition(settings->value("State/trimlow",0).toInt()); 697 | bitSettingsFirstRun->setBit(1,0); 698 | } 699 | 700 | } 701 | bool NeuralStylerWindow::isImageOrGif() 702 | { 703 | QFileInfo fileInfo(QFile(ui->lineEditFilePath->text())); 704 | 705 | if(fileInfo.suffix().toLower().compare("jpeg")==0) 706 | return true; 707 | if(fileInfo.suffix().toLower().compare("jpg")==0) 708 | return true; 709 | if(fileInfo.suffix().toLower().compare("png")==0) 710 | return true; 711 | if(fileInfo.suffix().toLower().compare("gif")==0) 712 | return true; 713 | if(fileInfo.suffix().toLower().compare("bmp")==0) 714 | return true; 715 | if(fileInfo.suffix().toLower().compare("ppm")==0) 716 | return true; 717 | if(fileInfo.suffix().toLower().compare("pnm")==0) 718 | return true; 719 | if(fileInfo.suffix().toLower().compare("pgm")==0) 720 | return true; 721 | if(fileInfo.suffix().toLower().compare("pbm")==0) 722 | return true; 723 | if(fileInfo.suffix().toLower().compare("webp")==0) 724 | return true; 725 | if(fileInfo.suffix().toLower().compare("bpg")==0) 726 | return true; 727 | 728 | return false; 729 | } 730 | bool NeuralStylerWindow::isGif() 731 | { 732 | QFileInfo fileInfo(QFile(ui->lineEditFilePath->text())); 733 | 734 | if(fileInfo.suffix().toLower().compare("gif")==0) 735 | return true; 736 | 737 | return false; 738 | } 739 | 740 | void NeuralStylerWindow::on_pushButtonPause_clicked() 741 | { 742 | if (ui->pushButtonPause->text().compare("Pause")==0){ 743 | ui->pushButtonPause->setText("Paused"); 744 | timer->stop(); 745 | ui->progressBarFrame->setEnabled(false); 746 | ui->progressBarOverall->setEnabled(false); 747 | } 748 | else{ 749 | 750 | ui->pushButtonPause->setText("Pause"); 751 | //resume 752 | chainerProcess(); 753 | timer->start(); 754 | ui->progressBarFrame->setEnabled(true); 755 | ui->progressBarOverall->setEnabled(true); 756 | } 757 | } 758 | 759 | void NeuralStylerWindow::on_checkBoxNoScale_clicked() 760 | { 761 | if(ui->checkBoxNoScale->isChecked()){ 762 | ui->comboBoxResolution->setDisabled(true); 763 | ui->checkBoxKeepAspectRatio->setDisabled(true); 764 | ui->lineEditHeight->setDisabled(true); 765 | ui->lineEditWidth->setDisabled(true); 766 | 767 | } 768 | else{ 769 | ui->comboBoxResolution->setDisabled(false); 770 | ui->checkBoxKeepAspectRatio->setDisabled(false); 771 | ui->lineEditHeight->setDisabled(false); 772 | ui->lineEditWidth->setDisabled(false); 773 | } 774 | } 775 | 776 | void NeuralStylerWindow::on_pushButonBrowseFileSave_clicked() 777 | { 778 | QString dir = paths->getDir(this,"Open a Directory for output:",""); 779 | if (dir.isEmpty()) 780 | return; 781 | 782 | ui->lineEditSavePath->setText(dir); 783 | settings->beginGroup("Main"); 784 | settings->setValue("destination", dir); 785 | settings->endGroup(); 786 | paths->setStyledVideoPath(ui->lineEditSavePath->text()); 787 | } 788 | 789 | void NeuralStylerWindow::on_actionGet_more_styles_triggered() 790 | { 791 | QDesktopServices::openUrl(QUrl("http://neuralstyler.com/styles.html")); 792 | } 793 | 794 | void NeuralStylerWindow::on_sliderStyleStrength_valueChanged(int value) 795 | { 796 | ui->labelStyleS->setText("Style strength :"+QString::number(value)+"%"); 797 | } 798 | 799 | 800 | void NeuralStylerWindow::on_comboBoxResolution_currentIndexChanged(const QString &arg1) 801 | { 802 | if (arg1.compare("Custom")==0) 803 | { 804 | ui->groupBoxRes->setVisible(true); 805 | 806 | } 807 | else{ 808 | ui->groupBoxRes->setVisible(false); 809 | } 810 | } 811 | void NeuralStylerWindow::engineState(bool isSave) 812 | { 813 | if (isSave){ 814 | settings->beginGroup("State"); 815 | settings->setValue("processfile", ui->lineEditFilePath->text()); 816 | settings->setValue("keepaspectratio", ui->checkBoxKeepAspectRatio->isChecked()); 817 | settings->setValue("noscale", ui->checkBoxNoScale->isChecked()); 818 | settings->setValue("resindex", ui->comboBoxResolution->currentIndex()); 819 | settings->setValue("width", ui->lineEditWidth->text()); 820 | settings->setValue("height", ui->lineEditHeight->text()); 821 | settings->setValue("height", ui->lineEditHeight->text()); 822 | settings->setValue("stylestrength", ui->sliderStyleStrength->value()); 823 | settings->setValue("trimup", ui->frameSlider->upperValue()); 824 | settings->setValue("trimlow", ui->frameSlider->lowerValue()); 825 | settings->endGroup(); 826 | 827 | } 828 | else{ 829 | 830 | ui->lineEditFilePath->setText(settings->value("State/processfile","").toString()); 831 | ui->checkBoxKeepAspectRatio->setChecked(settings->value("State/keepaspectratio",true).toBool()); 832 | ui->checkBoxNoScale->setChecked(settings->value("State/noscale",false).toBool()); 833 | ui->comboBoxResolution->setCurrentIndex(settings->value("State/resindex",0).toInt()); 834 | ui->sliderStyleStrength->setValue(settings->value("State/stylestrength",50).toInt()); 835 | if (ui->checkBoxNoScale->isChecked()){ 836 | ui->checkBoxKeepAspectRatio->setEnabled(false); 837 | ui->comboBoxResolution->setEnabled(false); 838 | ui->lineEditHeight->setEnabled(false); 839 | ui->lineEditWidth->setEnabled(false); 840 | } 841 | 842 | 843 | } 844 | 845 | } 846 | void NeuralStylerWindow::initVideoTrim() 847 | { 848 | ui->pushButtonPause->setEnabled(false); 849 | ui->pushButtonViewFrame->setEnabled(false); 850 | if (!isImageOrGif()){ 851 | ui->groupBox_2->setEnabled(true); 852 | videoTimeLabel->setText(""); 853 | if(mp){ 854 | mp=new Mplayer(); 855 | mp->setMplayerPath(mPath); 856 | connect(mp,SIGNAL(gotduration(float)),this,SLOT(setSliderRange(float))); 857 | connect(ui->frameSlider, SIGNAL(lowerValueChanged(int)), SLOT(seek(int))); 858 | connect(ui->frameSlider, SIGNAL(upperValueChanged(int)), SLOT(seek(int))); 859 | mp->setVideoWin(mplayerVideo->winId()); 860 | #ifdef Q_OS_LINUX 861 | mp->setScaling(261,181); 862 | #endif 863 | 864 | 865 | } 866 | //m_mpv->command(QStringList() << "loadfile" << QUrl::fromLocalFile(ui->lineEditFilePath->text()).toString()); 867 | mp->play( QUrl::fromLocalFile(ui->lineEditFilePath->text()).toString()); 868 | // const bool paused = m_mpv->getProperty("pause").toBool(); 869 | //if (!paused) 870 | // m_mpv->setProperty("pause", !paused); 871 | }else{ 872 | ui->groupBox_2->setEnabled(false); 873 | bitSettingsFirstRun->setBit(1,false); 874 | 875 | } 876 | } 877 | void NeuralStylerWindow::showEvent(QShowEvent * event) 878 | { 879 | if (bitSettingsFirstRun->testBit(0)){ 880 | initVideoTrim(); 881 | bitSettingsFirstRun->setBit(0,false); 882 | } 883 | 884 | } 885 | void NeuralStylerWindow::closeEvent(QCloseEvent *event) 886 | { 887 | event->ignore(); 888 | if (ui->pushButtonProcess->text().compare("Cancel Neural Styling")==0) 889 | {if (QMessageBox::Yes == QMessageBox::question(this, "Close Confirmation?", 890 | "You haven't finished styling yet. Do you want to exit without finishing?", 891 | QMessageBox::Yes|QMessageBox::No)) 892 | { 893 | if(ffmpeg){ 894 | ffmpeg->write("q\n"); 895 | ffmpeg->waitForBytesWritten(); 896 | } 897 | // qDebug()<<"wrote q"; 898 | event->accept(); 899 | 900 | } 901 | } 902 | else 903 | { 904 | event->accept(); 905 | 906 | 907 | } 908 | engineState(true); 909 | 910 | } 911 | 912 | 913 | void NeuralStylerWindow::on_action_Help_triggered() 914 | { 915 | QDesktopServices::openUrl(QUrl("http://neuralstyler.com/help/")); 916 | } 917 | 918 | void NeuralStylerWindow::on_pushButtonReset_clicked() 919 | { 920 | ui->comboBoxResolution->setCurrentIndex(0); 921 | ui->sliderStyleStrength->setValue(50); 922 | ui->checkBoxKeepAspectRatio->setChecked(true); 923 | ui->checkBoxNoScale->setChecked(false); 924 | ui->comboBoxResolution->setEnabled(true); 925 | } 926 | 927 | void NeuralStylerWindow::on_pushButtonViewFrame_clicked() 928 | { 929 | 930 | frameDlg=new FrameDialog(this); 931 | QObject::connect(this,SIGNAL(updatePreviewFrame(QString)),frameDlg,SLOT(LoadFrame(QString))); 932 | frameDlg->show(); 933 | } 934 | void NeuralStylerWindow::dropEvent(QDropEvent* event) 935 | { 936 | const QMimeData* mimeData = event->mimeData(); 937 | 938 | if (mimeData->hasUrls()) 939 | { 940 | QStringList pathList; 941 | QList urlList = mimeData->urls(); 942 | 943 | // extract the local paths of the files 944 | for (int i = 0; i < urlList.size(); i++) 945 | { 946 | pathList.append(urlList.at(i).toLocalFile()); 947 | } 948 | if(pathList.size()>0) 949 | ui->lineEditFilePath->setText(pathList.at(0)); 950 | initVideoTrim(); 951 | } 952 | //event->acceptProposedAction() 953 | } 954 | void NeuralStylerWindow::dragMoveEvent(QDragMoveEvent *event) 955 | { 956 | event->acceptProposedAction(); 957 | } 958 | void NeuralStylerWindow::dragEnterEvent(QDragEnterEvent *event) 959 | { 960 | if (event->mimeData()->hasUrls()) 961 | event->acceptProposedAction(); 962 | 963 | } 964 | -------------------------------------------------------------------------------- /neuralstylerwindow.h: -------------------------------------------------------------------------------- 1 | /* 2 | NeuralStyler,Artistic style for your videos/photos 3 | Copyright(C) 2016 Rupesh Sreeraman 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | You should have received a copy of the GNU General Public License 13 | along with this program; if not, write to the Free Software 14 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 15 | paint icon :http://findicons.com/icon/85674/paint?id=85674 16 | 17 | */ 18 | 19 | #ifndef NEURALSTYLERWINDOW_H 20 | #define NEURALSTYLERWINDOW_H 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include "qxtspanslider.h" 41 | #include 42 | #include "framedialog.h" 43 | #include 44 | #include 45 | #include 46 | #include 47 | namespace Ui { 48 | class NeuralStylerWindow; 49 | } 50 | 51 | class NeuralStylerWindow : public QMainWindow 52 | { 53 | Q_OBJECT 54 | 55 | public: 56 | explicit NeuralStylerWindow(QWidget *parent = 0); 57 | ~NeuralStylerWindow(); 58 | static int const EXIT_CODE_REBOOT = -123456789; 59 | 60 | signals: 61 | void updatePreviewFrame(QString); 62 | private slots: 63 | void on_pushButonBrowseFile_clicked(); 64 | void on_pushButtonProcess_clicked(); 65 | 66 | void fpsStarted(); 67 | void fpsCompleted(int ec); 68 | 69 | void frameExtratorStarted(); 70 | void frameExtratorCompleted(int ec); 71 | 72 | void audioExtratorStarted(); 73 | void audioExtratorCompleted(int ec); 74 | 75 | void fastNeuralStyleStarted(); 76 | void fastNeuralStyleCompleted(int ec); 77 | 78 | void styledVideoStarted(); 79 | void styledVideoCompleted(int ec); 80 | 81 | void gotFrame(QString fnum); 82 | 83 | void on_comboBoxStyles_currentIndexChanged(const QString &arg1); 84 | 85 | void on_pushButtonOpenOutput_clicked(); 86 | 87 | void on_actionAbout_triggered(); 88 | void update(); 89 | void finishStyling(); 90 | 91 | void seek(int pos); 92 | void setSliderRange(float duration); 93 | bool isImageOrGif(); 94 | bool isGif(); 95 | 96 | 97 | void on_pushButtonPause_clicked(); 98 | void on_checkBoxNoScale_clicked(); 99 | 100 | void on_pushButonBrowseFileSave_clicked(); 101 | 102 | void on_actionGet_more_styles_triggered(); 103 | 104 | void on_sliderStyleStrength_valueChanged(int value); 105 | 106 | void on_comboBoxResolution_currentIndexChanged(const QString &arg1); 107 | void engineState(bool save); 108 | void initVideoTrim(); 109 | 110 | void showEvent(QShowEvent * event); 111 | void closeEvent(QCloseEvent *event); 112 | 113 | 114 | void on_action_Help_triggered(); 115 | 116 | void on_pushButtonReset_clicked(); 117 | 118 | void on_pushButtonViewFrame_clicked(); 119 | void dropEvent(QDropEvent* event); 120 | void dragMoveEvent(QDragMoveEvent *event); 121 | void dragEnterEvent(QDragEnterEvent *event); 122 | 123 | private: 124 | Ui::NeuralStylerWindow *ui; 125 | 126 | QPointer ffmpeg; 127 | QPointer fastNeuralStyle; 128 | 129 | Paths *paths; 130 | //MpvWidget *m_mpv; 131 | QPointer mp; 132 | QLabel *mplayerVideo; 133 | 134 | QStringList lstFrames; 135 | 136 | void getFramePerSec();//Get fps using ffmpeg 137 | void extractFrames(); //Extract all frames 138 | void extractAudio(); //Extract Audio 139 | void styleFrames(); //Style frames 140 | void chainerProcess();//invoke fast neural style transfer 141 | void createStyledVideo();//Save video 142 | 143 | long processingFrameCount; 144 | 145 | QString strFramesPerSec; 146 | QString strDuration; 147 | long elaspsedTime; 148 | int64_t frameCount; 149 | 150 | AboutDialog *aboutDlg; 151 | StyleIntensityDialog *styleIntensityDlg; 152 | FrameDialog *frameDlg; 153 | QTime tElapsed; 154 | QTimer *timer; 155 | 156 | QLabel *videoTimeLabel; 157 | QLabel *videoStatusLabel; 158 | 159 | 160 | QSettings *settings; 161 | QBitArray *bitSettingsFirstRun; 162 | 163 | QString mPath; 164 | 165 | }; 166 | 167 | #endif // NEURALSTYLERWINDOW_H 168 | -------------------------------------------------------------------------------- /neuralstylerwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | NeuralStylerWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 850 10 | 400 11 | 12 | 13 | 14 | 15 | 850 16 | 400 17 | 18 | 19 | 20 | 21 | 870 22 | 400 23 | 24 | 25 | 26 | true 27 | 28 | 29 | NeuralStyler 30 | 31 | 32 | 33 | :/neuralstyler-logo.jpg:/neuralstyler-logo.jpg 34 | 35 | 36 | 37 | 38 | 39 | 10 40 | 350 41 | 531 42 | 20 43 | 44 | 45 | 46 | 47 | 6 48 | 49 | 50 | 51 | 52 | Elapsed Time 53 | 54 | 55 | 00:00:00 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 2 64 | 18 65 | 66 | 67 | 68 | 69 | 16777215 70 | 18 71 | 72 | 73 | 74 | Overall progres 75 | 76 | 77 | 0 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 10 87 | 120 88 | 531 89 | 191 90 | 91 | 92 | 93 | true 94 | 95 | 96 | Options 97 | 98 | 99 | 100 | 101 | 190 102 | 30 103 | 167 104 | 25 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 68 113 | 16777215 114 | 115 | 116 | 117 | Resolution: 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 320x240 126 | 127 | 128 | 129 | 130 | 160x120 131 | 132 | 133 | 134 | 135 | 480x320 136 | 137 | 138 | 139 | 140 | 640x480 141 | 142 | 143 | 144 | 145 | 1024x768 146 | 147 | 148 | 149 | 150 | Custom 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 10 161 | 30 162 | 166 163 | 147 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 0 172 | 16 173 | 174 | 175 | 176 | Style : 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 120 185 | 90 186 | 187 | 188 | 189 | No preview 190 | 191 | 192 | true 193 | 194 | 195 | Qt::AlignCenter 196 | 197 | 198 | 199 | 200 | 201 | 202 | Qt::Horizontal 203 | 204 | 205 | 206 | 40 207 | 20 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 120 217 | 0 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 190 228 | 60 229 | 141 230 | 21 231 | 232 | 233 | 234 | Keep Aspect Ratio 235 | 236 | 237 | 238 | 239 | 240 | 190 241 | 90 242 | 111 243 | 16 244 | 245 | 246 | 247 | Disable size scaling 248 | 249 | 250 | No scaling 251 | 252 | 253 | 254 | 255 | 256 | 190 257 | 120 258 | 291 259 | 21 260 | 261 | 262 | 263 | 264 | 265 | 266 | Style strength : 267 | 268 | 269 | 270 | 271 | 272 | 273 | 100 274 | 275 | 276 | 50 277 | 278 | 279 | Qt::Horizontal 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 360 289 | 0 290 | 131 291 | 61 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 10 301 | 30 302 | 40 303 | 20 304 | 305 | 306 | 307 | 308 | 40 309 | 16777215 310 | 311 | 312 | 313 | 9999 314 | 315 | 316 | Width 317 | 318 | 319 | 320 | 321 | 322 | 70 323 | 30 324 | 40 325 | 20 326 | 327 | 328 | 329 | 330 | 40 331 | 16777215 332 | 333 | 334 | 335 | 9999 336 | 337 | 338 | Height 339 | 340 | 341 | 342 | 343 | 344 | 60 345 | 30 346 | 21 347 | 16 348 | 349 | 350 | 351 | X 352 | 353 | 354 | 355 | 356 | 357 | 358 | 190 359 | 150 360 | 75 361 | 23 362 | 363 | 364 | 365 | Reset 366 | 367 | 368 | 369 | 370 | 371 | 372 | 560 373 | 20 374 | 281 375 | 351 376 | 377 | 378 | 379 | true 380 | 381 | 382 | Video Section 383 | 384 | 385 | 386 | 387 | 10 388 | 210 389 | 261 390 | 20 391 | 392 | 393 | 394 | Qt::Horizontal 395 | 396 | 397 | 398 | 399 | 400 | 401 | 11 402 | 20 403 | 531 404 | 25 405 | 406 | 407 | 408 | 409 | 410 | 411 | Video/image file: 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 370 420 | 0 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 0 430 | 0 431 | 432 | 433 | 434 | 435 | 31 436 | 0 437 | 438 | 439 | 440 | 441 | 31 442 | 16777215 443 | 444 | 445 | 446 | ... 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 11 456 | 50 457 | 531 458 | 25 459 | 460 | 461 | 462 | 463 | 464 | 465 | Save Path: 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 370 474 | 0 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 0 484 | 0 485 | 486 | 487 | 488 | 489 | 31 490 | 0 491 | 492 | 493 | 494 | 495 | 31 496 | 16777215 497 | 498 | 499 | 500 | ... 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 11 510 | 81 511 | 536 512 | 37 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 155 521 | 35 522 | 523 | 524 | 525 | 526 | 155 527 | 16777215 528 | 529 | 530 | 531 | Open Styled Videos 532 | 533 | 534 | 535 | :/images/fileopen.png:/images/fileopen.png 536 | 537 | 538 | 539 | 21 540 | 21 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 120 550 | 35 551 | 552 | 553 | 554 | 555 | 120 556 | 35 557 | 558 | 559 | 560 | Preview Frame 561 | 562 | 563 | 564 | :/images/preview.png:/images/preview.png 565 | 566 | 567 | 568 | 22 569 | 22 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 81 579 | 35 580 | 581 | 582 | 583 | 584 | 81 585 | 16777215 586 | 587 | 588 | 589 | Pause 590 | 591 | 592 | 593 | :/images/pause.png:/images/pause.png 594 | 595 | 596 | 597 | 24 598 | 24 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 160 608 | 35 609 | 610 | 611 | 612 | 613 | 160 614 | 35 615 | 616 | 617 | 618 | Create Artistic Style 619 | 620 | 621 | 622 | :/images/paint.png:/images/paint.png 623 | 624 | 625 | 626 | 24 627 | 24 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 11 638 | 322 639 | 529 640 | 20 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 270 649 | 0 650 | 651 | 652 | 653 | 654 | 270 655 | 16777215 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 251 668 | 18 669 | 670 | 671 | 672 | 673 | 251 674 | 18 675 | 676 | 677 | 678 | 0 679 | 680 | 681 | 682 | 683 | 684 | layoutWidget 685 | layoutWidget 686 | layoutWidget 687 | layoutWidget 688 | layoutWidget 689 | groupBox 690 | groupBox_2 691 | 692 | 693 | 694 | 695 | 696 | 0 697 | 0 698 | 850 699 | 20 700 | 701 | 702 | 703 | 704 | Help 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | About 715 | 716 | 717 | 718 | 719 | Get more styles 720 | 721 | 722 | 723 | 724 | &Help 725 | 726 | 727 | 728 | 729 | 730 | 731 | QxtSpanSlider 732 | QSlider 733 |
qxtspanslider.h
734 |
735 |
736 | 737 | 738 | 739 | 740 |
741 | -------------------------------------------------------------------------------- /paths.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | NeuralStyler,Artistic style for your videos/photos 3 | Copyright(C) 2016 Rupesh Sreeraman 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | You should have received a copy of the GNU General Public License 13 | along with this program; if not, write to the Free Software 14 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 15 | */ 16 | 17 | #include "paths.h" 18 | 19 | Paths::Paths(QString appPath) 20 | { 21 | 22 | //All path init 23 | strAppPath=appPath+"/"; 24 | strFramePath = appPath+"/frames"; 25 | strAudioPath = appPath+"/audio"; 26 | strStyledFramePath = appPath+"/sframes"; 27 | strStyledVideoPath = appPath+"/styledvideo"; 28 | strStylePath=appPath+"/styles"; 29 | 30 | qDebug()<<"Paths:App"< 20 | #include 21 | #include 22 | #include 23 | 24 | class Paths 25 | { 26 | public: 27 | Paths(QString appPath); 28 | 29 | inline void setStyledVideoPath(QString path){strStyledVideoPath=path;} 30 | inline QString getStyledVideoPath(){return strStyledVideoPath+"/";} 31 | inline QString getAudioPath(){return strAudioPath+"/";} 32 | inline QString getStylePath(){return strStylePath+"/";} 33 | inline QString getFramePath(){return strFramePath+"/";} 34 | inline QString getAppPath(){return strAppPath;} 35 | inline QString getStyledFramePath(){return strStyledFramePath+"/";} 36 | 37 | void ensureFramePath(); 38 | void ensureAudioPath(); 39 | void ensureStyledFramePath(); 40 | void ensureStyledVideoPath(); 41 | QString getDir(QWidget *parent , QString caption, QString root); 42 | 43 | private: 44 | QString strAppPath; 45 | QString strFramePath; 46 | QString strAudioPath; 47 | QString strStyledFramePath; 48 | QString strStyledVideoPath; 49 | QString strStylePath; 50 | void ensurePath(QString pth); 51 | }; 52 | 53 | 54 | #endif // PATHS_H 55 | -------------------------------------------------------------------------------- /python-part/generate.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import argparse 3 | from PIL import Image 4 | import time 5 | 6 | import chainer 7 | from chainer import cuda, Variable, serializers 8 | from net import * 9 | 10 | parser = argparse.ArgumentParser(description='Real-time style transfer image generator') 11 | parser.add_argument('input') 12 | parser.add_argument('--gpu', '-g', default=-1, type=int, 13 | help='GPU ID (negative value indicates CPU)') 14 | parser.add_argument('--model', '-m', default='models/style.model', type=str) 15 | parser.add_argument('--out', '-o', default='out.jpg', type=str) 16 | args = parser.parse_args() 17 | 18 | model = FastStyleNet() 19 | serializers.load_npz(args.model, model) 20 | if args.gpu >= 0: 21 | cuda.get_device(args.gpu).use() 22 | model.to_gpu() 23 | xp = np if args.gpu < 0 else cuda.cupy 24 | 25 | start = time.time() 26 | image = xp.asarray(Image.open(args.input).convert('RGB'), dtype=xp.float32).transpose(2, 0, 1) 27 | image = image.reshape((1,) + image.shape) 28 | x = Variable(image) 29 | 30 | y = model(x) 31 | result = cuda.to_cpu(y.data) 32 | 33 | result = result.transpose(0, 2, 3, 1) 34 | result = result.reshape((result.shape[1:])) 35 | result = np.uint8(result) 36 | print time.time() - start, 'sec' 37 | 38 | Image.fromarray(result).save(args.out) 39 | -------------------------------------------------------------------------------- /python-part/net.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | import numpy as np 4 | import chainer 5 | import chainer.links as L 6 | import chainer.functions as F 7 | from chainer import Variable 8 | 9 | class ResidualBlock(chainer.Chain): 10 | def __init__(self, n_in, n_out, stride=1, ksize=3): 11 | w = math.sqrt(2) 12 | super(ResidualBlock, self).__init__( 13 | c1=L.Convolution2D(n_in, n_out, ksize, stride, 1, w), 14 | c2=L.Convolution2D(n_out, n_out, ksize, 1, 1, w), 15 | b1=L.BatchNormalization(n_out), 16 | b2=L.BatchNormalization(n_out) 17 | ) 18 | 19 | def __call__(self, x, test): 20 | h = F.relu(self.b1(self.c1(x), test=test)) 21 | h = self.b2(self.c2(h), test=test) 22 | if x.data.shape != h.data.shape: 23 | xp = chainer.cuda.get_array_module(x.data) 24 | n, c, hh, ww = x.data.shape 25 | pad_c = h.data.shape[1] - c 26 | p = xp.zeros((n, pad_c, hh, ww), dtype=xp.float32) 27 | p = chainer.Variable(p, volatile=test) 28 | x = F.concat((p, x)) 29 | if x.data.shape[2:] != h.data.shape[2:]: 30 | x = F.average_pooling_2d(x, 1, 2) 31 | return h + x 32 | 33 | class FastStyleNet(chainer.Chain): 34 | def __init__(self): 35 | super(FastStyleNet, self).__init__( 36 | c1=L.Convolution2D(3, 32, 9, stride=1, pad=4), 37 | c2=L.Convolution2D(32, 64, 4, stride=2, pad=1), 38 | c3=L.Convolution2D(64, 128, 4,stride=2, pad=1), 39 | r1=ResidualBlock(128, 128), 40 | r2=ResidualBlock(128, 128), 41 | r3=ResidualBlock(128, 128), 42 | r4=ResidualBlock(128, 128), 43 | r5=ResidualBlock(128, 128), 44 | d1=L.Deconvolution2D(128, 64, 4, stride=2, pad=1), 45 | d2=L.Deconvolution2D(64, 32, 4, stride=2, pad=1), 46 | d3=L.Deconvolution2D(32, 3, 9, stride=1, pad=4), 47 | b1=L.BatchNormalization(32), 48 | b2=L.BatchNormalization(64), 49 | b3=L.BatchNormalization(128), 50 | b4=L.BatchNormalization(64), 51 | b5=L.BatchNormalization(32), 52 | ) 53 | 54 | def __call__(self, x, test=False): 55 | h = self.b1(F.elu(self.c1(x)), test=test) 56 | h = self.b2(F.elu(self.c2(h)), test=test) 57 | h = self.b3(F.elu(self.c3(h)), test=test) 58 | h = self.r1(h, test=test) 59 | h = self.r2(h, test=test) 60 | h = self.r3(h, test=test) 61 | h = self.r4(h, test=test) 62 | h = self.r5(h, test=test) 63 | h = self.b4(F.elu(self.d1(h)), test=test) 64 | h = self.b5(F.elu(self.d2(h)), test=test) 65 | y = self.d3(h) 66 | return (F.tanh(y)+1)*127.5 67 | 68 | class VGG(chainer.Chain): 69 | def __init__(self): 70 | super(VGG, self).__init__( 71 | conv1_1=L.Convolution2D(3, 64, 3, stride=1, pad=1), 72 | conv1_2=L.Convolution2D(64, 64, 3, stride=1, pad=1), 73 | 74 | conv2_1=L.Convolution2D(64, 128, 3, stride=1, pad=1), 75 | conv2_2=L.Convolution2D(128, 128, 3, stride=1, pad=1), 76 | 77 | conv3_1=L.Convolution2D(128, 256, 3, stride=1, pad=1), 78 | conv3_2=L.Convolution2D(256, 256, 3, stride=1, pad=1), 79 | conv3_3=L.Convolution2D(256, 256, 3, stride=1, pad=1), 80 | 81 | conv4_1=L.Convolution2D(256, 512, 3, stride=1, pad=1), 82 | conv4_2=L.Convolution2D(512, 512, 3, stride=1, pad=1), 83 | conv4_3=L.Convolution2D(512, 512, 3, stride=1, pad=1), 84 | 85 | conv5_1=L.Convolution2D(512, 512, 3, stride=1, pad=1), 86 | conv5_2=L.Convolution2D(512, 512, 3, stride=1, pad=1), 87 | conv5_3=L.Convolution2D(512, 512, 3, stride=1, pad=1) 88 | ) 89 | self.train = False 90 | self.mean = np.asarray(120, dtype=np.float32) 91 | 92 | def preprocess(self, image): 93 | return np.rollaxis(image - self.mean, 2) 94 | 95 | def __call__(self, x): 96 | y1 = F.relu(self.conv1_2(F.relu(self.conv1_1(x)))) 97 | h = F.max_pooling_2d(y1, 2, stride=2) 98 | y2 = F.relu(self.conv2_2(F.relu(self.conv2_1(h)))) 99 | h = F.max_pooling_2d(y2, 2, stride=2) 100 | y3 = F.relu(self.conv3_3(F.relu(self.conv3_2(F.relu(self.conv3_1(h)))))) 101 | h = F.max_pooling_2d(y3, 2, stride=2) 102 | y4 = F.relu(self.conv4_3(F.relu(self.conv4_2(F.relu(self.conv4_1(h)))))) 103 | return [y1, y2, y3, y4] 104 | -------------------------------------------------------------------------------- /qxtspanslider.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) Qxt Foundation. Some rights reserved. 4 | ** 5 | ** This file is part of the QxtGui module of the Qxt library. 6 | ** 7 | ** This library is free software; you can redistribute it and/or modify it 8 | ** under the terms of the Common Public License, version 1.0, as published 9 | ** by IBM, and/or under the terms of the GNU Lesser General Public License, 10 | ** version 2.1, as published by the Free Software Foundation. 11 | ** 12 | ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY 13 | ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY 14 | ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR 15 | ** FITNESS FOR A PARTICULAR PURPOSE. 16 | ** 17 | ** You should have received a copy of the CPL and the LGPL along with this 18 | ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files 19 | ** included with the source distribution for more information. 20 | ** If you did not receive a copy of the licenses, contact the Qxt Foundation. 21 | ** 22 | ** 23 | ** 24 | ****************************************************************************/ 25 | // Modified by Graham Rowlands 26 | 27 | #include "qxtspanslider.h" 28 | #include "qxtspanslider_p.h" 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | QxtSpanSliderPrivate::QxtSpanSliderPrivate() : 37 | lower(0), 38 | upper(0), 39 | lowerPos(0), 40 | upperPos(0), 41 | offset(0), 42 | position(0), 43 | lastPressed(NoHandle), 44 | mainControl(LowerHandle), 45 | lowerPressed(QStyle::SC_None), 46 | upperPressed(QStyle::SC_None), 47 | movement(QxtSpanSlider::FreeMovement), 48 | firstMovement(false), 49 | blockTracking(false), 50 | fixedInterval(false) 51 | { 52 | } 53 | 54 | // TODO: get rid of this in Qt 4.3 55 | void QxtSpanSliderPrivate::initStyleOption(QStyleOptionSlider* option, SpanHandle handle) const 56 | { 57 | if (!option) 58 | return; 59 | 60 | const QSlider* p = &qxt_p(); 61 | option->initFrom(p); 62 | option->subControls = QStyle::SC_None; 63 | option->activeSubControls = QStyle::SC_None; 64 | option->orientation = p->orientation(); 65 | option->maximum = p->maximum(); 66 | option->minimum = p->minimum(); 67 | option->tickPosition = p->tickPosition(); 68 | option->tickInterval = p->tickInterval(); 69 | option->upsideDown = (p->orientation() == Qt::Horizontal) ? 70 | (p->invertedAppearance() != (option->direction == Qt::RightToLeft)) : (!p->invertedAppearance()); 71 | option->direction = Qt::LeftToRight; // we use the upsideDown option instead 72 | option->sliderPosition = (handle == LowerHandle ? lowerPos : upperPos); 73 | option->sliderValue = (handle == LowerHandle ? lower : upper); 74 | option->singleStep = p->singleStep(); 75 | option->pageStep = p->pageStep(); 76 | if (p->orientation() == Qt::Horizontal) 77 | option->state |= QStyle::State_Horizontal; 78 | } 79 | 80 | int QxtSpanSliderPrivate::pixelPosToRangeValue(int pos) const 81 | { 82 | QStyleOptionSlider opt; 83 | initStyleOption(&opt); 84 | 85 | int sliderMin = 0; 86 | int sliderMax = 0; 87 | int sliderLength = 0; 88 | const QSlider* p = &qxt_p(); 89 | const QRect gr = p->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, p); 90 | const QRect sr = p->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, p); 91 | if (p->orientation() == Qt::Horizontal) 92 | { 93 | sliderLength = sr.width(); 94 | sliderMin = gr.x(); 95 | sliderMax = gr.right() - sliderLength + 1; 96 | } 97 | else 98 | { 99 | sliderLength = sr.height(); 100 | sliderMin = gr.y(); 101 | sliderMax = gr.bottom() - sliderLength + 1; 102 | } 103 | return QStyle::sliderValueFromPosition(p->minimum(), p->maximum(), pos - sliderMin, 104 | sliderMax - sliderMin, opt.upsideDown); 105 | } 106 | 107 | void QxtSpanSliderPrivate::handleMousePress(const QPoint& pos, QStyle::SubControl& control, int value, SpanHandle handle) 108 | { 109 | QStyleOptionSlider opt; 110 | initStyleOption(&opt, handle); 111 | QSlider* p = &qxt_p(); 112 | const QStyle::SubControl oldControl = control; 113 | control = p->style()->hitTestComplexControl(QStyle::CC_Slider, &opt, pos, p); 114 | const QRect sr = p->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, p); 115 | if (control == QStyle::SC_SliderHandle) 116 | { 117 | position = value; 118 | offset = pick(pos - sr.topLeft()); 119 | lastPressed = handle; 120 | p->setSliderDown(true); 121 | } 122 | if (control != oldControl) 123 | p->update(sr); 124 | } 125 | 126 | void QxtSpanSliderPrivate::setupPainter(QPainter* painter, Qt::Orientation orientation, qreal x1, qreal y1, qreal x2, qreal y2) const 127 | { 128 | QColor highlight = qxt_p().palette().color(QPalette::Highlight); 129 | QLinearGradient gradient(x1, y1, x2, y2); 130 | gradient.setColorAt(0, highlight.dark(120)); 131 | gradient.setColorAt(1, highlight.light(108)); 132 | painter->setBrush(gradient); 133 | 134 | if (orientation == Qt::Horizontal) 135 | painter->setPen(QPen(highlight.dark(130), 0)); 136 | else 137 | painter->setPen(QPen(highlight.dark(150), 0)); 138 | } 139 | 140 | void QxtSpanSliderPrivate::drawSpan(QStylePainter* painter, const QRect& rect) const 141 | { 142 | QStyleOptionSlider opt; 143 | initStyleOption(&opt); 144 | const QSlider* p = &qxt_p(); 145 | 146 | // area 147 | QRect groove = p->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, p); 148 | if (opt.orientation == Qt::Horizontal) 149 | groove.adjust(0, 0, -1, 0); 150 | else 151 | groove.adjust(0, 0, 0, -1); 152 | 153 | // pen & brush 154 | painter->setPen(QPen(p->palette().color(QPalette::Dark).light(110), 0)); 155 | if (opt.orientation == Qt::Horizontal) 156 | setupPainter(painter, opt.orientation, groove.center().x(), groove.top(), groove.center().x(), groove.bottom()); 157 | else 158 | setupPainter(painter, opt.orientation, groove.left(), groove.center().y(), groove.right(), groove.center().y()); 159 | 160 | // draw groove 161 | painter->drawRect(rect.intersected(groove)); 162 | } 163 | 164 | void QxtSpanSliderPrivate::drawHandle(QStylePainter* painter, SpanHandle handle) const 165 | { 166 | QStyleOptionSlider opt; 167 | initStyleOption(&opt, handle); 168 | opt.subControls = QStyle::SC_SliderHandle; 169 | QStyle::SubControl pressed = (handle == LowerHandle ? lowerPressed : upperPressed); 170 | if (pressed == QStyle::SC_SliderHandle) 171 | { 172 | opt.activeSubControls = pressed; 173 | opt.state |= QStyle::State_Sunken; 174 | } 175 | painter->drawComplexControl(QStyle::CC_Slider, opt); 176 | } 177 | 178 | void QxtSpanSliderPrivate::triggerAction(QAbstractSlider::SliderAction action, bool main) 179 | { 180 | int value = 0; 181 | bool no = false; 182 | bool up = false; 183 | const int min = qxt_p().minimum(); 184 | const int max = qxt_p().maximum(); 185 | const SpanHandle altControl = (mainControl == LowerHandle ? UpperHandle : LowerHandle); 186 | 187 | blockTracking = true; 188 | 189 | switch (action) 190 | { 191 | case QAbstractSlider::SliderSingleStepAdd: 192 | if ((main && mainControl == UpperHandle) || (!main && altControl == UpperHandle)) 193 | { 194 | value = qBound(min, upper + qxt_p().singleStep(), max); 195 | up = true; 196 | break; 197 | } 198 | value = qBound(min, lower + qxt_p().singleStep(), max); 199 | break; 200 | case QAbstractSlider::SliderSingleStepSub: 201 | if ((main && mainControl == UpperHandle) || (!main && altControl == UpperHandle)) 202 | { 203 | value = qBound(min, upper - qxt_p().singleStep(), max); 204 | up = true; 205 | break; 206 | } 207 | value = qBound(min, lower - qxt_p().singleStep(), max); 208 | break; 209 | case QAbstractSlider::SliderToMinimum: 210 | value = min; 211 | if ((main && mainControl == UpperHandle) || (!main && altControl == UpperHandle)) 212 | up = true; 213 | break; 214 | case QAbstractSlider::SliderToMaximum: 215 | value = max; 216 | if ((main && mainControl == UpperHandle) || (!main && altControl == UpperHandle)) 217 | up = true; 218 | break; 219 | case QAbstractSlider::SliderMove: 220 | if ((main && mainControl == UpperHandle) || (!main && altControl == UpperHandle)) 221 | up = true; 222 | case QAbstractSlider::SliderNoAction: 223 | no = true; 224 | break; 225 | default: 226 | qWarning("QxtSpanSliderPrivate::triggerAction: Unknown action"); 227 | break; 228 | } 229 | 230 | if (!no && !up) 231 | { 232 | if (movement == QxtSpanSlider::NoCrossing) 233 | value = qMin(value, upper); 234 | else if (movement == QxtSpanSlider::NoOverlapping) 235 | value = qMin(value, upper - 1); 236 | 237 | if (movement == QxtSpanSlider::FreeMovement && value > upper) 238 | { 239 | swapControls(); 240 | qxt_p().setUpperPosition(value); 241 | } 242 | else 243 | { 244 | qxt_p().setLowerPosition(value); 245 | } 246 | } 247 | else if (!no) 248 | { 249 | if (movement == QxtSpanSlider::NoCrossing) 250 | value = qMax(value, lower); 251 | else if (movement == QxtSpanSlider::NoOverlapping) 252 | value = qMax(value, lower + 1); 253 | 254 | if (movement == QxtSpanSlider::FreeMovement && value < lower) 255 | { 256 | swapControls(); 257 | qxt_p().setLowerPosition(value); 258 | } 259 | else 260 | { 261 | qxt_p().setUpperPosition(value); 262 | } 263 | } 264 | 265 | blockTracking = false; 266 | qxt_p().setLowerValue(lowerPos); 267 | qxt_p().setUpperValue(upperPos); 268 | } 269 | 270 | void QxtSpanSliderPrivate::swapControls() 271 | { 272 | qSwap(lower, upper); 273 | qSwap(lowerPressed, upperPressed); 274 | lastPressed = (lastPressed == LowerHandle ? UpperHandle : LowerHandle); 275 | mainControl = (mainControl == LowerHandle ? UpperHandle : LowerHandle); 276 | } 277 | 278 | void QxtSpanSliderPrivate::updateRange(int min, int max) 279 | { 280 | Q_UNUSED(min); 281 | Q_UNUSED(max); 282 | // setSpan() takes care of keeping span in range 283 | qxt_p().setSpan(lower, upper); 284 | } 285 | 286 | void QxtSpanSliderPrivate::movePressedHandle() 287 | { 288 | switch (lastPressed) 289 | { 290 | case QxtSpanSliderPrivate::LowerHandle: 291 | if (lowerPos != lower) 292 | { 293 | bool main = (mainControl == QxtSpanSliderPrivate::LowerHandle); 294 | triggerAction(QAbstractSlider::SliderMove, main); 295 | } 296 | break; 297 | case QxtSpanSliderPrivate::UpperHandle: 298 | if (upperPos != upper) 299 | { 300 | bool main = (mainControl == QxtSpanSliderPrivate::UpperHandle); 301 | triggerAction(QAbstractSlider::SliderMove, main); 302 | } 303 | break; 304 | default: 305 | break; 306 | } 307 | } 308 | 309 | /*! 310 | \class QxtSpanSlider 311 | \inmodule QxtGui 312 | \brief The QxtSpanSlider widget is a QSlider with two handles. 313 | 314 | QxtSpanSlider is a slider with two handles. QxtSpanSlider is 315 | handy for letting user to choose an span between min/max. 316 | 317 | The span color is calculated based on QPalette::Highlight. 318 | 319 | The keys are bound according to the following table: 320 | \table 321 | \header \o Orientation \o Key \o Handle 322 | \row \o Qt::Horizontal \o Qt::Key_Left \o lower 323 | \row \o Qt::Horizontal \o Qt::Key_Right \o lower 324 | \row \o Qt::Horizontal \o Qt::Key_Up \o upper 325 | \row \o Qt::Horizontal \o Qt::Key_Down \o upper 326 | \row \o Qt::Vertical \o Qt::Key_Up \o lower 327 | \row \o Qt::Vertical \o Qt::Key_Down \o lower 328 | \row \o Qt::Vertical \o Qt::Key_Left \o upper 329 | \row \o Qt::Vertical \o Qt::Key_Right \o upper 330 | \endtable 331 | 332 | Keys are bound by the time the slider is created. A key is bound 333 | to same handle for the lifetime of the slider. So even if the handle 334 | representation might change from lower to upper, the same key binding 335 | remains. 336 | 337 | \image qxtspanslider.png "QxtSpanSlider in Plastique style." 338 | 339 | \bold {Note:} QxtSpanSlider inherits QSlider for implementation specific 340 | reasons. Adjusting any single handle specific properties like 341 | \list 342 | \o QAbstractSlider::sliderPosition 343 | \o QAbstractSlider::value 344 | \endlist 345 | has no effect. However, all slider specific properties like 346 | \list 347 | \o QAbstractSlider::invertedAppearance 348 | \o QAbstractSlider::invertedControls 349 | \o QAbstractSlider::minimum 350 | \o QAbstractSlider::maximum 351 | \o QAbstractSlider::orientation 352 | \o QAbstractSlider::pageStep 353 | \o QAbstractSlider::singleStep 354 | \o QSlider::tickInterval 355 | \o QSlider::tickPosition 356 | \endlist 357 | are taken into consideration. 358 | */ 359 | 360 | /*! 361 | \enum QxtSpanSlider::HandleMovementMode 362 | 363 | This enum describes the available handle movement modes. 364 | 365 | \value FreeMovement The handles can be moved freely. 366 | \value NoCrossing The handles cannot cross, but they can still overlap each other. The lower and upper values can be the same. 367 | \value NoOverlapping The handles cannot overlap each other. The lower and upper values cannot be the same. 368 | */ 369 | 370 | /*! 371 | \fn QxtSpanSlider::lowerValueChanged(int lower) 372 | 373 | This signal is emitted whenever the \a lower value has changed. 374 | */ 375 | 376 | /*! 377 | \fn QxtSpanSlider::upperValueChanged(int upper) 378 | 379 | This signal is emitted whenever the \a upper value has changed. 380 | */ 381 | 382 | /*! 383 | \fn QxtSpanSlider::spanChanged(int lower, int upper) 384 | 385 | This signal is emitted whenever both the \a lower and the \a upper 386 | values have changed ie. the span has changed. 387 | */ 388 | 389 | /*! 390 | \fn QxtSpanSlider::lowerPositionChanged(int lower) 391 | 392 | This signal is emitted whenever the \a lower position has changed. 393 | */ 394 | 395 | /*! 396 | \fn QxtSpanSlider::upperPositionChanged(int upper) 397 | 398 | This signal is emitted whenever the \a upper position has changed. 399 | */ 400 | 401 | /*! 402 | Constructs a new QxtSpanSlider with \a parent. 403 | */ 404 | QxtSpanSlider::QxtSpanSlider(QWidget* parent) : QSlider(parent) 405 | { 406 | QXT_INIT_PRIVATE(QxtSpanSlider); 407 | connect(this, SIGNAL(rangeChanged(int, int)), &qxt_d(), SLOT(updateRange(int, int))); 408 | connect(this, SIGNAL(sliderReleased()), &qxt_d(), SLOT(movePressedHandle())); 409 | } 410 | 411 | /*! 412 | Constructs a new QxtSpanSlider with \a orientation and \a parent. 413 | */ 414 | QxtSpanSlider::QxtSpanSlider(Qt::Orientation orientation, QWidget* parent) : QSlider(orientation, parent) 415 | { 416 | QXT_INIT_PRIVATE(QxtSpanSlider); 417 | connect(this, SIGNAL(rangeChanged(int, int)), &qxt_d(), SLOT(updateRange(int, int))); 418 | connect(this, SIGNAL(sliderReleased()), &qxt_d(), SLOT(movePressedHandle())); 419 | } 420 | 421 | /*! 422 | Destructs the span slider. 423 | */ 424 | QxtSpanSlider::~QxtSpanSlider() 425 | { 426 | } 427 | 428 | /*! 429 | \property QxtSpanSlider::handleMovementMode 430 | \brief the handle movement mode 431 | */ 432 | QxtSpanSlider::HandleMovementMode QxtSpanSlider::handleMovementMode() const 433 | { 434 | return qxt_d().movement; 435 | } 436 | 437 | void QxtSpanSlider::setHandleMovementMode(QxtSpanSlider::HandleMovementMode mode) 438 | { 439 | qxt_d().movement = mode; 440 | } 441 | 442 | /*! 443 | \property QxtSpanSlider::lowerValue 444 | \brief the lower value of the span 445 | */ 446 | int QxtSpanSlider::lowerValue() const 447 | { 448 | return qMin(qxt_d().lower, qxt_d().upper); 449 | } 450 | 451 | void QxtSpanSlider::setLowerValue(int lower) 452 | { 453 | setSpan(lower, qxt_d().upper); 454 | } 455 | 456 | /*! 457 | \property QxtSpanSlider::upperValue 458 | \brief the upper value of the span 459 | */ 460 | int QxtSpanSlider::upperValue() const 461 | { 462 | return qMax(qxt_d().lower, qxt_d().upper); 463 | } 464 | 465 | void QxtSpanSlider::setUpperValue(int upper) 466 | { 467 | setSpan(qxt_d().lower, upper); 468 | } 469 | 470 | /*! 471 | Sets the span from \a lower to \a upper. 472 | */ 473 | void QxtSpanSlider::setSpan(int lower, int upper) 474 | { 475 | const int low = qBound(minimum(), qMin(lower, upper), maximum()); 476 | const int upp = qBound(minimum(), qMax(lower, upper), maximum()); 477 | if (low != qxt_d().lower || upp != qxt_d().upper) 478 | { 479 | if (low != qxt_d().lower) 480 | { 481 | qxt_d().lower = low; 482 | qxt_d().lowerPos = low; 483 | emit lowerValueChanged(low); 484 | } 485 | if (upp != qxt_d().upper) 486 | { 487 | qxt_d().upper = upp; 488 | qxt_d().upperPos = upp; 489 | emit upperValueChanged(upp); 490 | } 491 | emit spanChanged(qxt_d().lower, qxt_d().upper); 492 | update(); 493 | } 494 | } 495 | 496 | /*! 497 | \property QxtSpanSlider::lowerPosition 498 | \brief the lower position of the span 499 | */ 500 | int QxtSpanSlider::lowerPosition() const 501 | { 502 | return qxt_d().lowerPos; 503 | } 504 | 505 | void QxtSpanSlider::setLowerPosition(int lower) 506 | { 507 | if (qxt_d().lowerPos != lower) 508 | { 509 | qxt_d().lowerPos = lower; 510 | if (!hasTracking()) 511 | update(); 512 | if (isSliderDown()) 513 | emit lowerPositionChanged(lower); 514 | if (hasTracking() && !qxt_d().blockTracking) 515 | { 516 | bool main = (qxt_d().mainControl == QxtSpanSliderPrivate::LowerHandle); 517 | qxt_d().triggerAction(SliderMove, main); 518 | } 519 | } 520 | } 521 | 522 | /*! 523 | \property QxtSpanSlider::upperPosition 524 | \brief the upper position of the span 525 | */ 526 | int QxtSpanSlider::upperPosition() const 527 | { 528 | return qxt_d().upperPos; 529 | } 530 | 531 | void QxtSpanSlider::setUpperPosition(int upper) 532 | { 533 | if (qxt_d().upperPos != upper) 534 | { 535 | qxt_d().upperPos = upper; 536 | if (!hasTracking()) 537 | update(); 538 | if (isSliderDown()) 539 | emit upperPositionChanged(upper); 540 | if (hasTracking() && !qxt_d().blockTracking) 541 | { 542 | bool main = (qxt_d().mainControl == QxtSpanSliderPrivate::UpperHandle); 543 | qxt_d().triggerAction(SliderMove, main); 544 | } 545 | } 546 | } 547 | 548 | /*! 549 | \reimp 550 | */ 551 | void QxtSpanSlider::keyPressEvent(QKeyEvent* event) 552 | { 553 | QSlider::keyPressEvent(event); 554 | 555 | bool main = true; 556 | SliderAction action = SliderNoAction; 557 | switch (event->key()) 558 | { 559 | case Qt::Key_Left: 560 | main = (orientation() == Qt::Horizontal); 561 | action = !invertedAppearance() ? SliderSingleStepSub : SliderSingleStepAdd; 562 | break; 563 | case Qt::Key_Right: 564 | main = (orientation() == Qt::Horizontal); 565 | action = !invertedAppearance() ? SliderSingleStepAdd : SliderSingleStepSub; 566 | break; 567 | case Qt::Key_Up: 568 | main = (orientation() == Qt::Vertical); 569 | action = invertedControls() ? SliderSingleStepSub : SliderSingleStepAdd; 570 | break; 571 | case Qt::Key_Down: 572 | main = (orientation() == Qt::Vertical); 573 | action = invertedControls() ? SliderSingleStepAdd : SliderSingleStepSub; 574 | break; 575 | case Qt::Key_Home: 576 | main = (qxt_d().mainControl == QxtSpanSliderPrivate::LowerHandle); 577 | action = SliderToMinimum; 578 | break; 579 | case Qt::Key_End: 580 | main = (qxt_d().mainControl == QxtSpanSliderPrivate::UpperHandle); 581 | action = SliderToMaximum; 582 | break; 583 | default: 584 | event->ignore(); 585 | break; 586 | } 587 | 588 | if (action) 589 | qxt_d().triggerAction(action, main); 590 | } 591 | 592 | /*! 593 | \reimp 594 | */ 595 | void QxtSpanSlider::mousePressEvent(QMouseEvent* event) 596 | { 597 | if (minimum() == maximum() || (event->buttons() ^ event->button())) 598 | { 599 | event->ignore(); 600 | return; 601 | } 602 | 603 | if (event->modifiers() & Qt::ShiftModifier) { 604 | qxt_d().fixedInterval = true; 605 | } 606 | 607 | qxt_d().handleMousePress(event->pos(), qxt_d().upperPressed, qxt_d().upper, QxtSpanSliderPrivate::UpperHandle); 608 | if (qxt_d().upperPressed != QStyle::SC_SliderHandle) 609 | qxt_d().handleMousePress(event->pos(), qxt_d().lowerPressed, qxt_d().lower, QxtSpanSliderPrivate::LowerHandle); 610 | 611 | qxt_d().firstMovement = true; 612 | event->accept(); 613 | } 614 | 615 | /*! 616 | \reimp 617 | */ 618 | void QxtSpanSlider::mouseMoveEvent(QMouseEvent* event) 619 | { 620 | if (qxt_d().lowerPressed != QStyle::SC_SliderHandle && qxt_d().upperPressed != QStyle::SC_SliderHandle) 621 | { 622 | event->ignore(); 623 | return; 624 | } 625 | 626 | QStyleOptionSlider opt; 627 | qxt_d().initStyleOption(&opt); 628 | const int m = style()->pixelMetric(QStyle::PM_MaximumDragDistance, &opt, this); 629 | int newPosition = qxt_d().pixelPosToRangeValue(qxt_d().pick(event->pos()) - qxt_d().offset); 630 | if (m >= 0) 631 | { 632 | const QRect r = rect().adjusted(-m, -m, m, m); 633 | if (!r.contains(event->pos())) 634 | { 635 | newPosition = qxt_d().position; 636 | } 637 | } 638 | 639 | // pick the preferred handle on the first movement 640 | if (qxt_d().firstMovement) 641 | { 642 | if (qxt_d().lower == qxt_d().upper) 643 | { 644 | if (newPosition < lowerValue()) 645 | { 646 | qxt_d().swapControls(); 647 | qxt_d().firstMovement = false; 648 | } 649 | } 650 | else 651 | { 652 | qxt_d().firstMovement = false; 653 | } 654 | } 655 | 656 | if (qxt_d().lowerPressed == QStyle::SC_SliderHandle) 657 | { 658 | if (qxt_d().movement == NoCrossing) 659 | { 660 | newPosition = qMin(newPosition, upperValue()); 661 | } 662 | else if (qxt_d().movement == NoOverlapping) 663 | { 664 | if (qxt_d().fixedInterval) 665 | { 666 | int span = qxt_d().upperPos - qxt_d().lowerPos; 667 | newPosition = qMin(newPosition, upperValue() - 1); 668 | newPosition = qMin(newPosition, maximum() - span); 669 | setUpperPosition(newPosition + span); 670 | } 671 | else 672 | { 673 | newPosition = qMin(newPosition, upperValue() - 1); 674 | } 675 | } 676 | 677 | if (qxt_d().movement == FreeMovement && newPosition > qxt_d().upper) 678 | { 679 | qxt_d().swapControls(); 680 | setUpperPosition(newPosition); 681 | } 682 | else 683 | { 684 | setLowerPosition(newPosition); 685 | } 686 | } 687 | else if (qxt_d().upperPressed == QStyle::SC_SliderHandle) 688 | { 689 | if (qxt_d().movement == NoCrossing) 690 | newPosition = qMax(newPosition, lowerValue()); 691 | else if (qxt_d().movement == NoOverlapping) 692 | { 693 | if (qxt_d().fixedInterval) 694 | { 695 | int span = qxt_d().upperPos - qxt_d().lowerPos; 696 | newPosition = qMax(newPosition, lowerValue() + 1); 697 | newPosition = qMax(newPosition, span); 698 | setLowerPosition(newPosition - span); 699 | } 700 | else 701 | { 702 | newPosition = qMax(newPosition, lowerValue() + 1); 703 | } 704 | } 705 | if (qxt_d().movement == FreeMovement && newPosition < qxt_d().lower) 706 | { 707 | qxt_d().swapControls(); 708 | setLowerPosition(newPosition); 709 | } 710 | else 711 | { 712 | setUpperPosition(newPosition); 713 | } 714 | } 715 | event->accept(); 716 | } 717 | 718 | /*! 719 | \reimp 720 | */ 721 | void QxtSpanSlider::mouseReleaseEvent(QMouseEvent* event) 722 | { 723 | qxt_d().fixedInterval = false; 724 | QSlider::mouseReleaseEvent(event); 725 | setSliderDown(false); 726 | qxt_d().lowerPressed = QStyle::SC_None; 727 | qxt_d().upperPressed = QStyle::SC_None; 728 | update(); 729 | } 730 | 731 | /*! 732 | \reimp 733 | */ 734 | void QxtSpanSlider::paintEvent(QPaintEvent* event) 735 | { 736 | Q_UNUSED(event); 737 | QStylePainter painter(this); 738 | 739 | // groove & ticks 740 | QStyleOptionSlider opt; 741 | qxt_d().initStyleOption(&opt); 742 | opt.sliderValue = 0; 743 | opt.sliderPosition = 0; 744 | opt.subControls = QStyle::SC_SliderGroove | QStyle::SC_SliderTickmarks; 745 | painter.drawComplexControl(QStyle::CC_Slider, opt); 746 | 747 | // handle rects 748 | opt.sliderPosition = qxt_d().lowerPos; 749 | const QRect lr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); 750 | const int lrv = qxt_d().pick(lr.center()); 751 | opt.sliderPosition = qxt_d().upperPos; 752 | const QRect ur = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); 753 | const int urv = qxt_d().pick(ur.center()); 754 | 755 | // span 756 | const int minv = qMin(lrv, urv); 757 | const int maxv = qMax(lrv, urv); 758 | const QPoint c = QRect(lr.center(), ur.center()).center(); 759 | QRect spanRect; 760 | if (orientation() == Qt::Horizontal) 761 | spanRect = QRect(QPoint(minv, c.y() - 2), QPoint(maxv, c.y() + 1)); 762 | else 763 | spanRect = QRect(QPoint(c.x() - 2, minv), QPoint(c.x() + 1, maxv)); 764 | qxt_d().drawSpan(&painter, spanRect); 765 | 766 | // handles 767 | switch (qxt_d().lastPressed) 768 | { 769 | case QxtSpanSliderPrivate::LowerHandle: 770 | qxt_d().drawHandle(&painter, QxtSpanSliderPrivate::UpperHandle); 771 | qxt_d().drawHandle(&painter, QxtSpanSliderPrivate::LowerHandle); 772 | break; 773 | case QxtSpanSliderPrivate::UpperHandle: 774 | default: 775 | qxt_d().drawHandle(&painter, QxtSpanSliderPrivate::LowerHandle); 776 | qxt_d().drawHandle(&painter, QxtSpanSliderPrivate::UpperHandle); 777 | break; 778 | } 779 | } 780 | -------------------------------------------------------------------------------- /qxtspanslider.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) Qxt Foundation. Some rights reserved. 4 | ** 5 | ** This file is part of the QxtGui module of the Qxt library. 6 | ** 7 | ** This library is free software; you can redistribute it and/or modify it 8 | ** under the terms of the Common Public License, version 1.0, as published 9 | ** by IBM, and/or under the terms of the GNU Lesser General Public License, 10 | ** version 2.1, as published by the Free Software Foundation. 11 | ** 12 | ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY 13 | ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY 14 | ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR 15 | ** FITNESS FOR A PARTICULAR PURPOSE. 16 | ** 17 | ** You should have received a copy of the CPL and the LGPL along with this 18 | ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files 19 | ** included with the source distribution for more information. 20 | ** If you did not receive a copy of the licenses, contact the Qxt Foundation. 21 | ** 22 | ** 23 | ** 24 | ****************************************************************************/ 25 | // Modified by Graham Rowlands 26 | 27 | #ifndef QXTSPANSLIDER_H 28 | #define QXTSPANSLIDER_H 29 | 30 | #define QXT_GUI_EXPORT Q_DECL_IMPORT 31 | #define QXT_CORE_EXPORT Q_DECL_IMPORT 32 | #define QXT_DECLARE_PRIVATE(PUB) friend class PUB##Private; QxtPrivateInterface qxt_d; 33 | #define QXT_DECLARE_PUBLIC(PUB) friend class PUB; 34 | #define QXT_INIT_PRIVATE(PUB) qxt_d.setPublic(this); 35 | #define QXT_D(PUB) PUB##Private& d = qxt_d() 36 | #define QXT_P(PUB) PUB& p = qxt_p() 37 | 38 | #include 39 | 40 | template 41 | class QxtPrivate 42 | { 43 | public: 44 | virtual ~QxtPrivate() 45 | {} 46 | inline void QXT_setPublic(PUB* pub) 47 | { 48 | qxt_p_ptr = pub; 49 | } 50 | 51 | protected: 52 | inline PUB& qxt_p() 53 | { 54 | return *qxt_p_ptr; 55 | } 56 | inline const PUB& qxt_p() const 57 | { 58 | return *qxt_p_ptr; 59 | } 60 | 61 | private: 62 | PUB* qxt_p_ptr; 63 | }; 64 | 65 | template 66 | class QxtPrivateInterface 67 | { 68 | friend class QxtPrivate; 69 | public: 70 | QxtPrivateInterface() 71 | { 72 | pvt = new PVT; 73 | } 74 | ~QxtPrivateInterface() 75 | { 76 | delete pvt; 77 | } 78 | 79 | inline void setPublic(PUB* pub) 80 | { 81 | pvt->QXT_setPublic(pub); 82 | } 83 | inline PVT& operator()() 84 | { 85 | return *static_cast(pvt); 86 | } 87 | inline const PVT& operator()() const 88 | { 89 | return *static_cast(pvt); 90 | } 91 | private: 92 | QxtPrivateInterface(const QxtPrivateInterface&) { } 93 | QxtPrivateInterface& operator=(const QxtPrivateInterface&) { } 94 | QxtPrivate* pvt; 95 | }; 96 | 97 | class QxtSpanSliderPrivate; 98 | 99 | class QxtSpanSlider : public QSlider 100 | { 101 | Q_OBJECT 102 | QXT_DECLARE_PRIVATE(QxtSpanSlider) 103 | Q_PROPERTY(int lowerValue READ lowerValue WRITE setLowerValue) 104 | Q_PROPERTY(int upperValue READ upperValue WRITE setUpperValue) 105 | Q_PROPERTY(int lowerPosition READ lowerPosition WRITE setLowerPosition) 106 | Q_PROPERTY(int upperPosition READ upperPosition WRITE setUpperPosition) 107 | Q_PROPERTY(HandleMovementMode handleMovementMode READ handleMovementMode WRITE setHandleMovementMode) 108 | Q_ENUMS(HandleMovementMode) 109 | 110 | public: 111 | explicit QxtSpanSlider(QWidget* parent = 0); 112 | explicit QxtSpanSlider(Qt::Orientation orientation, QWidget* parent = 0); 113 | virtual ~QxtSpanSlider(); 114 | 115 | enum HandleMovementMode 116 | { 117 | FreeMovement, 118 | NoCrossing, 119 | NoOverlapping 120 | }; 121 | 122 | HandleMovementMode handleMovementMode() const; 123 | void setHandleMovementMode(HandleMovementMode mode); 124 | 125 | int lowerValue() const; 126 | int upperValue() const; 127 | 128 | int lowerPosition() const; 129 | int upperPosition() const; 130 | 131 | public Q_SLOTS: 132 | void setLowerValue(int lower); 133 | void setUpperValue(int upper); 134 | void setSpan(int lower, int upper); 135 | 136 | void setLowerPosition(int lower); 137 | void setUpperPosition(int upper); 138 | 139 | Q_SIGNALS: 140 | void spanChanged(int lower, int upper); 141 | void lowerValueChanged(int lower); 142 | void upperValueChanged(int upper); 143 | 144 | void lowerPositionChanged(int lower); 145 | void upperPositionChanged(int upper); 146 | 147 | protected: 148 | virtual void keyPressEvent(QKeyEvent* event); 149 | virtual void mousePressEvent(QMouseEvent* event); 150 | virtual void mouseMoveEvent(QMouseEvent* event); 151 | virtual void mouseReleaseEvent(QMouseEvent* event); 152 | virtual void paintEvent(QPaintEvent* event); 153 | }; 154 | 155 | #endif // QXTSPANSLIDER_H 156 | -------------------------------------------------------------------------------- /qxtspanslider_p.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) Qxt Foundation. Some rights reserved. 4 | ** 5 | ** This file is part of the QxtGui module of the Qxt library. 6 | ** 7 | ** This library is free software; you can redistribute it and/or modify it 8 | ** under the terms of the Common Public License, version 1.0, as published 9 | ** by IBM, and/or under the terms of the GNU Lesser General Public License, 10 | ** version 2.1, as published by the Free Software Foundation. 11 | ** 12 | ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY 13 | ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY 14 | ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR 15 | ** FITNESS FOR A PARTICULAR PURPOSE. 16 | ** 17 | ** You should have received a copy of the CPL and the LGPL along with this 18 | ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files 19 | ** included with the source distribution for more information. 20 | ** If you did not receive a copy of the licenses, contact the Qxt Foundation. 21 | ** 22 | ** 23 | ** 24 | ****************************************************************************/ 25 | // Modified by Graham Rowlands 26 | #ifndef QXTSPANSLIDER_P_H 27 | #define QXTSPANSLIDER_P_H 28 | 29 | #include 30 | #include 31 | #include "qxtspanslider.h" 32 | 33 | class QStylePainter; 34 | class QStyleOptionSlider; 35 | 36 | class QxtSpanSliderPrivate : public QObject, public QxtPrivate 37 | { 38 | Q_OBJECT 39 | 40 | public: 41 | QXT_DECLARE_PUBLIC(QxtSpanSlider) 42 | 43 | enum SpanHandle 44 | { 45 | NoHandle, 46 | LowerHandle, 47 | UpperHandle 48 | }; 49 | 50 | QxtSpanSliderPrivate(); 51 | void initStyleOption(QStyleOptionSlider* option, SpanHandle handle = UpperHandle) const; 52 | int pick(const QPoint& pt) const 53 | { 54 | return qxt_p().orientation() == Qt::Horizontal ? pt.x() : pt.y(); 55 | } 56 | int pixelPosToRangeValue(int pos) const; 57 | void handleMousePress(const QPoint& pos, QStyle::SubControl& control, int value, SpanHandle handle); 58 | void drawHandle(QStylePainter* painter, SpanHandle handle) const; 59 | void setupPainter(QPainter* painter, Qt::Orientation orientation, qreal x1, qreal y1, qreal x2, qreal y2) const; 60 | void drawSpan(QStylePainter* painter, const QRect& rect) const; 61 | void triggerAction(QAbstractSlider::SliderAction action, bool main); 62 | void swapControls(); 63 | 64 | int lower; 65 | int upper; 66 | int lowerPos; 67 | int upperPos; 68 | int offset; 69 | int position; 70 | SpanHandle lastPressed; 71 | SpanHandle mainControl; 72 | QStyle::SubControl lowerPressed; 73 | QStyle::SubControl upperPressed; 74 | QxtSpanSlider::HandleMovementMode movement; 75 | bool firstMovement; 76 | bool blockTracking; 77 | bool fixedInterval; 78 | 79 | public slots: 80 | void updateRange(int min, int max); 81 | void movePressedHandle(); 82 | }; 83 | 84 | #endif // QXTSPANSLIDER_P_H 85 | -------------------------------------------------------------------------------- /stylechainer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | NeuralStyler,Artistic style for your videos/photos 3 | Copyright(C) 2016 Rupesh Sreeraman 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | You should have received a copy of the GNU General Public License 13 | along with this program; if not, write to the Free Software 14 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 15 | */ 16 | 17 | #include "stylechainer.h" 18 | 19 | StyleChainer::StyleChainer() 20 | { 21 | connect(this,SIGNAL(readyReadStandardOutput()),this,SLOT(readyReadStandardOutput())); 22 | connect(this,SIGNAL(readyReadStandardError()),this,SLOT(readyReadStandardError())); 23 | 24 | } 25 | void StyleChainer::readyReadStandardOutput() 26 | { 27 | 28 | strConsoleOut+=readAllStandardOutput(); 29 | qDebug()<< strConsoleOut; 30 | if (rx_time.indexIn(strConsoleOut)>-1) { 31 | 32 | qDebug()<start(strAppPath+"env/python.exe",arguments()); 48 | #endif 49 | #ifdef Q_OS_LINUX 50 | this->start(strAppPath+"env/bin/python",arguments()); 51 | # endif 52 | 53 | } 54 | 55 | -------------------------------------------------------------------------------- /stylechainer.h: -------------------------------------------------------------------------------- 1 | /* 2 | NeuralStyler,Artistic style for your videos/photos 3 | Copyright(C) 2016 Rupesh Sreeraman 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | You should have received a copy of the GNU General Public License 13 | along with this program; if not, write to the Free Software 14 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 15 | */ 16 | #ifndef STYLECHAINER_H 17 | #define STYLECHAINER_H 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | static QRegExp rx_time("(\\d*\\.\\d+)*.sec"); 25 | 26 | class StyleChainer: public QProcess 27 | { 28 | Q_OBJECT 29 | 30 | public: 31 | StyleChainer(); 32 | void setAppPath(QString appPath){strAppPath=appPath;} 33 | QString getProcessingTime(){return strElaspedTime;} 34 | 35 | 36 | public slots: 37 | void readyReadStandardOutput(); 38 | void readyReadStandardError(); 39 | void sytleIt(); 40 | 41 | private: 42 | QString strElaspedTime; 43 | QString strConsoleOut; 44 | QString strConsoleErr; 45 | QString strAppPath; 46 | }; 47 | 48 | #endif // STYLECHAINER_H 49 | -------------------------------------------------------------------------------- /styleintensitydialog.cpp: -------------------------------------------------------------------------------- 1 | #include "styleintensitydialog.h" 2 | #include "ui_styleintensitydialog.h" 3 | 4 | StyleIntensityDialog::StyleIntensityDialog(QWidget *parent,QString srcPath,QString stylePath,QString destPath) : 5 | QDialog(parent), 6 | ui(new Ui::StyleIntensityDialog) 7 | { 8 | ui->setupUi(this); 9 | // ui->sliderStyleIntensity->setValue(100); 10 | strSourcePath=srcPath; 11 | strStylePath=stylePath; 12 | strSavePath=destPath; 13 | QImage top(strStylePath); 14 | QImage bot(strSourcePath); 15 | // both images are opaque because JPEG has no alpha channel 16 | QPixmap combined(bot.size()); 17 | QPainter p(&combined); 18 | p.drawImage(QPoint(0, 0), bot); // drawn as-is 19 | p.setOpacity(1.0); 20 | p.drawImage(QPoint(0, 0), top); 21 | p.end(); 22 | ui->labelCanvas->setPixmap(combined); 23 | 24 | changeStyleStrength(50); 25 | ui->sliderStyleIntensity->setValue(50); 26 | if (QFile::exists(strSavePath)) 27 | QFile::remove(strSavePath); 28 | ui->labelCanvas->pixmap()->save(strSavePath); 29 | 30 | 31 | } 32 | 33 | StyleIntensityDialog::~StyleIntensityDialog() 34 | { 35 | delete ui; 36 | } 37 | 38 | void StyleIntensityDialog::on_sliderStyleIntensity_valueChanged(int value) 39 | { 40 | ui->label->setText("Style strength :"+QString::number(value)+"%"); 41 | changeStyleStrength(value); 42 | } 43 | 44 | 45 | void StyleIntensityDialog::on_pushButtonSave_clicked() 46 | { 47 | if (QFile::exists(strSavePath)) 48 | QFile::remove(strSavePath); 49 | ui->labelCanvas->pixmap()->save(strSavePath); 50 | 51 | 52 | } 53 | void StyleIntensityDialog::changeStyleStrength(int styleStrength) 54 | { 55 | QImage top(strStylePath); 56 | QImage bot(strSourcePath); 57 | QImage wm(":/images/wm.png"); 58 | 59 | QPixmap combined(bot.size()); 60 | QPainter p(&combined); 61 | 62 | p.drawImage(QPoint(0, 0), bot); // drawn as-is 63 | p.setOpacity(styleStrength/100.0); 64 | p.drawImage(QPoint(0, 0), top); 65 | p.end(); 66 | 67 | //Draw water mark 68 | QPainter p2(&combined); 69 | 70 | /* 71 | +---------------------------+ 72 | | 5 | 73 | |<----5------>wm<----5----->| 74 | | 5 | 75 | +---------------------------+ 76 | 77 | Rect width = wm.width+10 78 | Rect height =wm.height+10 79 | Rect x =imgwidth-width 80 | Rect y =img height-height 81 | */ 82 | int pad=8; 83 | int rectWidth = wm.width()+(pad*2); 84 | int rectHeight = wm.height()+(pad*2); 85 | int rectLeft = bot.width()-rectWidth; 86 | int rectTop = bot.height()-rectHeight; 87 | 88 | /* 89 | Water mark image 90 | Point x =rectLeft+pad 91 | Point y =rectTop+pad */ 92 | 93 | int wmLeft = rectLeft+pad; 94 | int wmTop = rectTop+pad; 95 | 96 | 97 | p2.fillRect(QRect(rectLeft,rectTop,rectWidth,rectHeight), QBrush(QColor(0, 0, 0, 128))); 98 | p2.drawImage(QPoint(wmLeft, wmTop), wm); 99 | p2.end(); 100 | 101 | ui->labelCanvas->setPixmap(combined); 102 | } 103 | -------------------------------------------------------------------------------- /styleintensitydialog.h: -------------------------------------------------------------------------------- 1 | #ifndef STYLEINTENSITYDIALOG_H 2 | #define STYLEINTENSITYDIALOG_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | namespace Ui { 10 | class StyleIntensityDialog; 11 | } 12 | 13 | class StyleIntensityDialog : public QDialog 14 | { 15 | Q_OBJECT 16 | 17 | public: 18 | explicit StyleIntensityDialog(QWidget *parent = 0,QString srcPath="",QString stylePath="",QString destPath=""); 19 | ~StyleIntensityDialog(); 20 | void changeStyleStrength(int styleStrength); 21 | 22 | private slots: 23 | void on_sliderStyleIntensity_valueChanged(int value); 24 | void on_pushButtonSave_clicked(); 25 | 26 | private: 27 | Ui::StyleIntensityDialog *ui; 28 | QString strStylePath; 29 | QString strSourcePath; 30 | QString strSavePath; 31 | 32 | }; 33 | 34 | #endif // STYLEINTENSITYDIALOG_H 35 | -------------------------------------------------------------------------------- /styleintensitydialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | StyleIntensityDialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 532 10 | 435 11 | 12 | 13 | 14 | Adjust Style Strength 15 | 16 | 17 | 18 | 19 | 20 | background-color: rgb(0, 0, 0); 21 | color: rgb(255, 255, 255); 22 | 23 | 24 | 100% 25 | 26 | 27 | Qt::AlignCenter 28 | 29 | 30 | 31 | 32 | 33 | 34 | Style strength: 35 | 36 | 37 | 38 | 39 | 40 | 41 | 100 42 | 43 | 44 | 100 45 | 46 | 47 | Qt::Horizontal 48 | 49 | 50 | 51 | 52 | 53 | 54 | Save 55 | 56 | 57 | 58 | :/images/filesave .png:/images/filesave .png 59 | 60 | 61 | 62 | 22 63 | 22 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /styles/cubist-style.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rupeshs/neuralstyler/ff4986fc77f4be6a0a0b10e4a9dc60e6057d0487/styles/cubist-style.jpg -------------------------------------------------------------------------------- /styles/cubist.model: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rupeshs/neuralstyler/ff4986fc77f4be6a0a0b10e4a9dc60e6057d0487/styles/cubist.model -------------------------------------------------------------------------------- /styles/edtaonisl-style.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rupeshs/neuralstyler/ff4986fc77f4be6a0a0b10e4a9dc60e6057d0487/styles/edtaonisl-style.jpg -------------------------------------------------------------------------------- /styles/edtaonisl.model: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rupeshs/neuralstyler/ff4986fc77f4be6a0a0b10e4a9dc60e6057d0487/styles/edtaonisl.model -------------------------------------------------------------------------------- /styles/hokusai-style.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rupeshs/neuralstyler/ff4986fc77f4be6a0a0b10e4a9dc60e6057d0487/styles/hokusai-style.jpg -------------------------------------------------------------------------------- /styles/hokusai.model: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rupeshs/neuralstyler/ff4986fc77f4be6a0a0b10e4a9dc60e6057d0487/styles/hokusai.model -------------------------------------------------------------------------------- /styles/hundertwasser-style.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rupeshs/neuralstyler/ff4986fc77f4be6a0a0b10e4a9dc60e6057d0487/styles/hundertwasser-style.jpg -------------------------------------------------------------------------------- /styles/hundertwasser.model: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rupeshs/neuralstyler/ff4986fc77f4be6a0a0b10e4a9dc60e6057d0487/styles/hundertwasser.model -------------------------------------------------------------------------------- /styles/kandinsky-style.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rupeshs/neuralstyler/ff4986fc77f4be6a0a0b10e4a9dc60e6057d0487/styles/kandinsky-style.jpg -------------------------------------------------------------------------------- /styles/kandinsky.model: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rupeshs/neuralstyler/ff4986fc77f4be6a0a0b10e4a9dc60e6057d0487/styles/kandinsky.model -------------------------------------------------------------------------------- /styles/seurat.model: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rupeshs/neuralstyler/ff4986fc77f4be6a0a0b10e4a9dc60e6057d0487/styles/seurat.model -------------------------------------------------------------------------------- /styles/starrynight-style.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rupeshs/neuralstyler/ff4986fc77f4be6a0a0b10e4a9dc60e6057d0487/styles/starrynight-style.jpg -------------------------------------------------------------------------------- /styles/starrynight.model: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rupeshs/neuralstyler/ff4986fc77f4be6a0a0b10e4a9dc60e6057d0487/styles/starrynight.model --------------------------------------------------------------------------------