├── .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 | 
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 | 
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 | 
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 | 
--------------------------------------------------------------------------------
/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 |
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 |
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
--------------------------------------------------------------------------------