All Classes Namespaces Functions Variables Enumerations Properties Pages
commandlineexporter.cpp
1 /*
2 
3 Pencil2D - Traditional Animation Software
4 Copyright (C) 2005-2007 Patrick Corrieri & Pascal Naidon
5 Copyright (C) 2012-2020 Matthew Chiawen Chang
6 
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; version 2 of the License.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15 
16 */
17 
18 #include <QFileInfo>
19 #include <QTextStream>
20 
21 #include "editor.h"
22 #include "fileformat.h"
23 #include "layercamera.h"
24 #include "layermanager.h"
25 #include "mainwindow2.h"
26 #include "movieexporter.h"
27 #include "object.h"
28 #include "playbackmanager.h"
29 
30 #include "commandlineexporter.h"
31 
33  mEditor(editor),
34  mOut(stdout, QIODevice::WriteOnly),
35  mErr(stderr, QIODevice::WriteOnly)
36 {
37 
38 }
39 
40 bool CommandLineExporter::process(const QString &inputPath,
41  const QStringList &outputPaths,
42  const QString &camera,
43  int width,
44  int height,
45  int startFrame,
46  int endFrame,
47  bool transparency)
48 {
49  LayerManager *layerManager = mEditor->layers();
50 
51  if(inputPath.isEmpty())
52  {
53  mErr << tr("Error: No input file specified. An input project file argument is required when output path(s) are specified.") << endl;
54  return false;
55  }
56 
57  Status s = mEditor->openObject(inputPath, [](int){}, [](int){});
58  if (!s.ok())
59  {
60  mErr << endl << endl << s.title() << endl << endl;
61  mErr << s.description() << endl << endl;
62  mErr << s.details().str() << endl << endl;
63  return false;
64  }
65 
66  LayerCamera *cameraLayer = nullptr;
67  if (!camera.isEmpty())
68  {
69  cameraLayer = dynamic_cast<LayerCamera*>(layerManager->findLayerByName(camera, Layer::CAMERA));
70  if (cameraLayer == nullptr)
71  {
72  mErr << tr("Warning: the specified camera layer %1 was not found, ignoring.").arg(camera) << endl;
73  }
74  }
75  if (cameraLayer == nullptr)
76  {
77  cameraLayer = dynamic_cast<LayerCamera*>(layerManager->getLastCameraLayer());
78  Q_ASSERT(cameraLayer);
79  }
80 
81  if (width < 0)
82  {
83  width = cameraLayer->getViewRect().width();
84  }
85  if (height < 0)
86  {
87  height = cameraLayer->getViewRect().height();
88  }
89  QSize exportSize(width, height);
90 
91  Q_ASSERT(startFrame >= 1);
92  if (endFrame < 0)
93  {
94  endFrame = layerManager->animationLength(endFrame < -1);
95  }
96 
97  Q_ASSERT(!outputPaths.empty());
98  for (const QString& outputPath : outputPaths)
99  {
100  // Detect format
101  QString format = detectFormatByFileNameExtension(outputPath);
102  if (format.isNull())
103  {
104  mErr << tr("Warning: Output format is not specified or unsupported. Using PNG.", "Command line warning") << endl;
105  format = "PNG";
106  }
107 
108  if (isMovieFormat(format))
109  {
110  exportMovie(outputPath, cameraLayer, exportSize, startFrame, endFrame, transparency);
111  continue;
112  }
113 
114  exportImageSequence(outputPath, format, cameraLayer, exportSize, startFrame, endFrame, transparency);
115  }
116 
117  return true;
118 }
119 
120 void CommandLineExporter::exportMovie(const QString &outputPath,
121  const LayerCamera *cameraLayer,
122  const QSize &exportSize,
123  int startFrame,
124  int endFrame,
125  bool transparency)
126 {
127  if (transparency)
128  {
129  mErr << tr("Warning: Transparency is not currently supported in movie files", "Command line warning") << endl;
130  }
131 
132  mOut << tr("Exporting movie...", "Command line task progress") << endl;
133 
134  ExportMovieDesc desc;
135  desc.strFileName = outputPath;
136  desc.startFrame = startFrame;
137  desc.endFrame = endFrame;
138  desc.fps = mEditor->playback()->fps();
139  desc.exportSize = exportSize;
140  desc.strCameraName = cameraLayer->name();
141 
142  MovieExporter ex;
143  ex.run(mEditor->object(), desc, [](float, float){}, [](float){}, [](const QString &){});
144  mOut << tr("Done.", "Command line task done") << endl;
145 }
146 
147 void CommandLineExporter::exportImageSequence(const QString &outputPath,
148  const QString &format,
149  const LayerCamera *cameraLayer,
150  const QSize &exportSize,
151  int startFrame,
152  int endFrame,
153  bool transparency)
154 {
155  mOut << tr("Exporting image sequence...", "Command line task progress") << endl;
156  mEditor->object()->exportFrames(startFrame,
157  endFrame,
158  cameraLayer,
159  exportSize,
160  outputPath,
161  format,
162  transparency,
163  false,
164  "",
165  true,
166  nullptr,
167  0);
168  mOut << tr("Done.", "Command line task done") << endl;
169 }
CommandLineExporter(Editor *editor)
Creates a new exporter instance.
int height() const const
QTextStream & endl(QTextStream &stream)
QString tr(const char *sourceText, const char *disambiguation, int n)
bool isNull() const const
bool empty() const const
bool isEmpty() const const
Status run(const Object *obj, const ExportMovieDesc &desc, std::function< void(float, float)> majorProgress, std::function< void(float)> minorProgress, std::function< void(QString)> progressMessage)
Begin exporting the movie described by exportDesc.
int width() const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
bool process(const QString &inputPath, const QStringList &outputPaths, const QString &camera, int width, int height, int startFrame, int endFrame, bool transparency)
Exports a Pencil2D file according to the specified options.
Definition: editor.h:55
int animationLength(bool includeSounds=true)
Get the length of current project.