Commit 57173609 authored by Dmitry Kazakov's avatar Dmitry Kazakov

Fix rendering of animation frames if the directory not exist

This patch fixes five bugs:

1) Recover warning dialog if the user tries to render animation
   frames into the directory with already existing frames. (QDir
   uses wildcard symbols instead of c-like patterns used by ffmpeg)

2) Warn the user if rendering of frame files didn't complete
   successfully. Previously, Krita just tried to run ffmped on the
   non-existing files.

3) Create the exporting directory if it doesn't exist.

4) Create the rendering directory if it doesn't exist.

5) If the user activates video-only mode and selects absolute file
   path, then export the frames into the same directory as the rendered
   file itself.
parent 8005a024
......@@ -226,6 +226,7 @@ void KisAnimationExporter::frameReadyToSave()
m_d->currentFrame = time + 1;
m_d->image->animationInterface()->requestFrameRegeneration(m_d->currentFrame, m_d->image->bounds());
} else {
m_d->status = result;
emit sigFinished();
}
}
......@@ -302,9 +303,15 @@ KisAnimationExportSaver::~KisAnimationExportSaver()
KisImportExportFilter::ConversionStatus KisAnimationExportSaver::exportAnimation(KisPropertiesConfigurationSP cfg)
{
QFileInfo info(savedFilesMask());
QFileInfo info(savedFilesMaskWildcard());
QDir dir(info.absolutePath());
if (!dir.exists()) {
dir.mkpath(info.absolutePath());
}
KIS_SAFE_ASSERT_RECOVER_NOOP(dir.exists());
QStringList filesList = dir.entryList({ info.fileName() });
if (!filesList.isEmpty()) {
......@@ -366,7 +373,7 @@ KisImportExportFilter::ConversionStatus KisAnimationExportSaver::saveFrameCallba
QRect rc = m_d->image->bounds();
KisPainter::copyAreaOptimized(rc.topLeft(), frame, m_d->tmpDevice, rc);
if (!m_d->tmpDoc->exportDocument(QUrl::fromLocalFile(filename), exportConfiguration)) {
status = KisImportExportFilter::InternalError;
status = KisImportExportFilter::CreationError;
}
return status;
......@@ -376,3 +383,8 @@ QString KisAnimationExportSaver::savedFilesMask() const
{
return m_d->filenamePrefix + "%04d" + m_d->filenameSuffix;
}
QString KisAnimationExportSaver::savedFilesMaskWildcard() const
{
return m_d->filenamePrefix + "????" + m_d->filenameSuffix;
}
......@@ -89,8 +89,17 @@ public:
KisImportExportFilter::ConversionStatus exportAnimation(KisPropertiesConfigurationSP cfg = 0);
/**
* A standard exported files mask for ffmpeg
*/
QString savedFilesMask() const;
/**
* Wildcards are not supported ffmpeg on Windows, so they are used for QDir
* only.
*/
QString savedFilesMaskWildcard() const;
private:
KisImportExportFilter::ConversionStatus saveFrameCallback(int time, KisPaintDeviceSP frame, KisPropertiesConfigurationSP exportConfiguration = 0);
......
......@@ -102,10 +102,14 @@ void AnimaterionRenderer::slotRenderAnimation()
.arg(extension);
KisAnimationExportSaver exporter(doc, baseFileName, sequenceConfig->getInt("first_frame"), sequenceConfig->getInt("last_frame"), sequenceConfig->getInt("sequence_start"));
bool success = exporter.exportAnimation(dlgAnimationRenderer.getFrameExportConfiguration()) == KisImportExportFilter::OK;
// the folder could have been read-only or something else could happen
if (success) {
KisImportExportFilter::ConversionStatus status =
exporter.exportAnimation(dlgAnimationRenderer.getFrameExportConfiguration());
if (status != KisImportExportFilter::OK) {
const QString msg = KisImportExportFilter::conversionStatusString(status);
QMessageBox::critical(0, i18nc("@title:window", "Krita"),
i18n("Could not export animation frames:\n%1", msg));
} else {
QString savedFilesMask = exporter.savedFilesMask();
KisPropertiesConfigurationSP videoConfig = dlgAnimationRenderer.getVideoConfiguration();
......@@ -118,9 +122,25 @@ void AnimaterionRenderer::slotRenderAnimation()
encoderConfig->setProperty("savedFilesMask", savedFilesMask);
}
const QDir framesDir(sequenceConfig->getString("directory"));
const QString fileName = videoConfig->getString("filename");
QString resultFile = QFileInfo(fileName).isAbsolute() ? fileName :
framesDir.absoluteFilePath(fileName);
{
const QFileInfo info(resultFile);
QDir dir(info.absolutePath());
if (!dir.exists()) {
dir.mkpath(info.absolutePath());
}
KIS_SAFE_ASSERT_RECOVER_NOOP(dir.exists());
}
QSharedPointer<KisImportExportFilter> encoder = dlgAnimationRenderer.encoderFilter();
encoder->setMimeType(mimetype.toLatin1());
QFile fi(videoConfig->getString("filename"));
QFile fi(resultFile);
KisImportExportFilter::ConversionStatus res;
if (!fi.open(QIODevice::WriteOnly)) {
qWarning() << "Could not open" << fi.fileName() << "for writing!";
......
......@@ -183,12 +183,37 @@ DlgAnimationRenderer::~DlgAnimationRenderer()
}
QString DlgAnimationRenderer::fetchRenderingDirectory() const
{
QString result = m_page->dirRequester->fileName();
if (m_page->shouldExportOnlyVideo->isChecked()) {
const QFileInfo info(fetchRenderingFileName());
if (info.isAbsolute()) {
result = info.absolutePath();
}
}
return result;
}
QString DlgAnimationRenderer::fetchRenderingFileName() const
{
QString filename = m_page->videoFilename->fileName();
if (QFileInfo(filename).completeSuffix().isEmpty()) {
QString mimetype = m_page->cmbRenderType->itemData(m_page->cmbRenderType->currentIndex()).toString();
filename += "." + KisMimeDatabase::suffixesForMimeType(mimetype).first();
}
return filename;
}
KisPropertiesConfigurationSP DlgAnimationRenderer::getSequenceConfiguration() const
{
KisPropertiesConfigurationSP cfg = new KisPropertiesConfiguration();
cfg->setProperty("basename", m_page->txtBasename->text());
cfg->setProperty("last_document_path", m_doc->localFilePath());
cfg->setProperty("directory", m_page->dirRequester->fileName());
cfg->setProperty("directory", fetchRenderingDirectory());
cfg->setProperty("first_frame", m_page->intStart->value());
cfg->setProperty("last_frame", m_page->intEnd->value());
cfg->setProperty("sequence_start", m_page->sequenceStart->value());
......@@ -224,7 +249,7 @@ KisPropertiesConfigurationSP DlgAnimationRenderer::getFrameExportConfiguration()
if (m_frameExportConfigWidget) {
KisPropertiesConfigurationSP cfg = m_frameExportConfigWidget->configuration();
cfg->setProperty("basename", m_page->txtBasename->text());
cfg->setProperty("directory", m_page->dirRequester->fileName());
cfg->setProperty("directory", fetchRenderingDirectory());
cfg->setProperty("first_frame", m_page->intStart->value());
cfg->setProperty("last_frame", m_page->intEnd->value());
cfg->setProperty("sequence_start", m_page->sequenceStart->value());
......@@ -243,12 +268,7 @@ KisPropertiesConfigurationSP DlgAnimationRenderer::getVideoConfiguration() const
}
KisPropertiesConfigurationSP cfg = new KisPropertiesConfiguration();
QString filename = m_page->videoFilename->fileName();
if (QFileInfo(filename).completeSuffix().isEmpty()) {
QString mimetype = m_page->cmbRenderType->itemData(m_page->cmbRenderType->currentIndex()).toString();
filename += "." + KisMimeDatabase::suffixesForMimeType(mimetype).first();
}
cfg->setProperty("filename", filename);
cfg->setProperty("filename", fetchRenderingFileName());
cfg->setProperty("first_frame", m_page->intStart->value());
cfg->setProperty("last_frame", m_page->intEnd->value());
cfg->setProperty("sequence_start", m_page->sequenceStart->value());
......@@ -277,7 +297,7 @@ KisPropertiesConfigurationSP DlgAnimationRenderer::getEncoderConfiguration() con
cfg = m_encoderConfigWidget->configuration();
}
cfg->setProperty("mimetype", m_page->cmbRenderType->currentData().toString());
cfg->setProperty("directory", m_page->dirRequester->fileName());
cfg->setProperty("directory", fetchRenderingDirectory());
cfg->setProperty("first_frame", m_page->intStart->value());
cfg->setProperty("last_frame", m_page->intEnd->value());
cfg->setProperty("sequence_start", m_page->sequenceStart->value());
......@@ -472,7 +492,7 @@ void DlgAnimationRenderer::slotExportTypeChanged()
}
// if only exporting video
if (m_page->shouldExportOnlyVideo) {
if (m_page->shouldExportOnlyVideo->isChecked()) {
m_page->cmbMimetype->setEnabled(false); // allow to change image format
m_page->imageSequenceOptionsGroup->setVisible(false);
m_page->videoOptionsGroup->setVisible(false); //shrinks the horizontal space temporarily to help resize() work
......
......@@ -83,6 +83,10 @@ protected Q_SLOTS:
void slotButtonClicked(int button);
private:
QString fetchRenderingDirectory() const;
QString fetchRenderingFileName() const;
private:
static QString findFFMpeg();
......
......@@ -227,6 +227,7 @@ KisImageBuilder_Result VideoSaver::encode(const QString &filename, KisProperties
KIS_SAFE_ASSERT_RECOVER_NOOP(configuration->hasProperty("first_frame"));
KIS_SAFE_ASSERT_RECOVER_NOOP(configuration->hasProperty("last_frame"));
KIS_SAFE_ASSERT_RECOVER_NOOP(configuration->hasProperty("include_audio"));
KIS_SAFE_ASSERT_RECOVER_NOOP(configuration->hasProperty("directory"));
const KisTimeRange clipRange(configuration->getInt("first_frame", fullRange.start()), configuration->getInt("last_frame", fullRange.end()));
const bool includeAudio = configuration->getBool("include_audio", true);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment