Commit 8211d811 authored by Boudewijn Rempt's avatar Boudewijn Rempt

Add a skeleton animation renderer plugin

This'll define the way an image sequence needs to be rendered,
and then render it to a sequence, then use any of the existing
video export plugins (csv, ffmpeg) to render to a video.
parent 1d18e6d2
......@@ -5,7 +5,7 @@ name="Krita"
version="92"
xsi:schemaLocation="http://www.kde.org/standards/kxmlgui/1.0 http://www.kde.org/standards/kxmlgui/1.0/kxmlgui.xsd">
<MenuBar>
<Menu name="file" noMerge="1">
<Menu name="file">
<text>&amp;File</text>
<Action name="file_new"/>
<Action name="file_open"/>
......@@ -17,12 +17,16 @@ xsi:schemaLocation="http://www.kde.org/standards/kxmlgui/1.0 http://www.kde.org
<Separator/>
<Action name="file_import_file"/>
<Action name="file_export_file"/>
<Separator/>
<Action name="file_export_pdf"/>
<Separator/>
<Action name="file_import_animation"/>
<Action name="file_export_animation"/>
<Action name="render_animation"/>
<Separator/>
<Action name="save_incremental_version"/>
<Action name="save_incremental_backup"/>
<Separator/>
<Action name="create_template"/>
<Action name="create_copy"/>
<!--Separator/>
......
......@@ -134,6 +134,30 @@
<isCheckable>false</isCheckable>
<statusTip></statusTip>
</Action>
<Action name="render_animation">
<icon></icon>
<text>&amp;Render Animation...</text>
<whatsThis></whatsThis>
<toolTip>Render Animation to GIF, Image Sequence or Video</toolTip>
<iconText>Render Animation</iconText>
<activationFlags>1000</activationFlags>
<activationConditions>0</activationConditions>
<shortcut></shortcut>
<isCheckable>false</isCheckable>
<statusTip></statusTip>
</Action>
<Action name="render_image_sequence_again">
<icon></icon>
<text>&amp;Render Image Sequence Again</text>
<whatsThis></whatsThis>
<toolTip>Render Animation to Image Sequence Again</toolTip>
<iconText>Render Animation</iconText>
<activationFlags>1000</activationFlags>
<activationConditions>0</activationConditions>
<shortcut></shortcut>
<isCheckable>false</isCheckable>
<statusTip></statusTip>
</Action>
<Action name="save_incremental_version">
<icon></icon>
<text>Save Incremental &amp;Version</text>
......
......@@ -14,6 +14,7 @@ add_subdirectory( shearimage )
add_subdirectory( layergroupswitcher )
add_subdirectory( resourcemanager )
add_subdirectory( layersplit )
add_subdirectory( animationrenderer )
# Allow to skip building GMIC plugin
option(WITH_GMIC "Build the G'Mic plugin" ON)
......
/*
* Copyright (c) 2016 Boudewijn Rempt <boud@valdyas.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "AnimationRenderer.h"
#include <klocalizedstring.h>
#include <kpluginfactory.h>
#include <kis_image.h>
#include <KisViewManager.h>
#include <kis_node_manager.h>
#include <kis_image_manager.h>
#include <kis_action.h>
#include <kis_properties_configuration.h>
#include "DlgAnimationRenderer.h"
K_PLUGIN_FACTORY_WITH_JSON(AnimaterionRendererFactory, "kritaanimationrenderer.json", registerPlugin<AnimaterionRenderer>();)
AnimaterionRenderer::AnimaterionRenderer(QObject *parent, const QVariantList &)
: KisViewPlugin(parent)
{
// Shows the big dialog
KisAction *action = createAction("render_animation");
connect(action, SIGNAL(triggered()), this, SLOT(slotRenderAnimation()));
// Re-renders the image sequence as defined in the last render
action = createAction("render_image_sequence_again");
connect(action, SIGNAL(triggered()), this, SLOT(slotRenderSequenceAgain()));
}
AnimaterionRenderer::~AnimaterionRenderer()
{
}
void AnimaterionRenderer::slotRenderAnimation()
{
KisImageWSP image = m_view->image();
if (!image) return;
DlgAnimaterionRenderer dlgAnimaterionRenderer(m_view->mainWindow());
dlgAnimaterionRenderer.setCaption(i18n("Render Animation"));
if (dlgAnimaterionRenderer.exec() == QDialog::Accepted) {
}
}
void AnimaterionRenderer::slotRenderSequenceAgain()
{
}
#include "AnimationRenderer.moc"
/*
* Copyright (c) 2016 Boudewijn Rempt <boud@valdyas.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#ifndef ANIMATIONRENDERERIMAGE_H
#define ANIMATIONRENDERERIMAGE_H
#include <QVariant>
#include <kis_view_plugin.h>
class AnimaterionRenderer : public KisViewPlugin
{
Q_OBJECT
public:
AnimaterionRenderer(QObject *parent, const QVariantList &);
virtual ~AnimaterionRenderer();
private Q_SLOTS:
void slotRenderAnimation();
void slotRenderSequenceAgain();
};
#endif // ANIMATIONRENDERERIMAGE_H
set(kritaanimationrenderer_SOURCES AnimationRenderer.cpp DlgAnimationRenderer.cpp )
ki18n_wrap_ui(kritaanimationrenderer_SOURCES wdg_animationrenderer.ui )
add_library(kritaanimationrenderer MODULE ${kritaanimationrenderer_SOURCES})
target_link_libraries(kritaanimationrenderer kritaui)
install(TARGETS kritaanimationrenderer DESTINATION ${KRITA_PLUGIN_INSTALL_DIR})
/*
* Copyright (c) 2016 Boudewijn Rempt <boud@valdyas.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "DlgAnimationRenderer.h"
#include <QPluginLoader>
#include <QJsonObject>
#include <klocalizedstring.h>
#include <kpluginfactory.h>
#include <kis_properties_configuration.h>
#include <kis_debug.h>
#include <KisMimeDatabase.h>
#include <KoJsonTrader.h>
#include <KisImportExportFilter.h>
DlgAnimaterionRenderer::DlgAnimaterionRenderer(QWidget *parent)
: KoDialog(parent)
{
setCaption(i18n("Render Animation"));
setButtons(Ok | Cancel);
setDefaultButton(Ok);
m_page = new WdgAnimaterionRenderer(this);
m_page->layout()->setMargin(0);
setMainWidget(m_page);
resize(m_page->sizeHint());
KoJsonTrader trader;
QList<QPluginLoader *>list = trader.query("Krita/AnimationExporter", "");
Q_FOREACH(QPluginLoader *loader, list) {
QJsonObject json = loader->metaData().value("MetaData").toObject();
Q_FOREACH(const QString &mimetype, json.value("X-KDE-Export").toString().split(",")) {
KLibFactory *factory = qobject_cast<KLibFactory *>(loader->instance());
if (!factory) {
warnUI << loader->errorString();
continue;
}
QObject* obj = factory->create<KisImportExportFilter>(parent);
if (!obj || !obj->inherits("KisImportExportFilter")) {
delete obj;
continue;
}
QSharedPointer<KisImportExportFilter> filter(static_cast<KisImportExportFilter*>(obj));
if (!filter) {
delete obj;
continue;
}
m_filters.append(filter);
// m_configWidgets.append(filter->createConfigurationWidget(m_page->grpRenderOptions));
// m_configWidgets.last()->setVisible(false);
m_page->cmbRenderType->addItem(KisMimeDatabase::descriptionForMimeType(mimetype));
}
}
connect(m_page->cmbRenderType, SIGNAL(activated(int)), this, SLOT(selectRenderType(int)));
}
DlgAnimaterionRenderer::~DlgAnimaterionRenderer()
{
delete m_page;
}
KisPropertiesConfigurationSP DlgAnimaterionRenderer::getSequenceConfiguration() const
{
KisPropertiesConfigurationSP cfg = new KisPropertiesConfiguration();
cfg->setProperty("basename", m_page->txtBasename->text());
cfg->setProperty("directory", m_page->dirRequester->fileName());
cfg->setProperty("first_frame", m_page->intStart->value());
cfg->setProperty("last_frame", m_page->intEnd->value());
cfg->setProperty("sequence_start", m_page->sequenceStart->value());
return cfg;
}
KisPropertiesConfigurationSP DlgAnimaterionRenderer::getVideoConfiguration() const
{
if (!m_page->grpRenderOptions->isChecked()) {
return 0;
}
KisPropertiesConfigurationSP cfg = new KisPropertiesConfiguration();
cfg->setProperty("filename", m_page->videoFilename->fileName());
cfg->setProperty("delete_sequence", m_page->chkDeleteSequence->isChecked());
return cfg;
}
KisPropertiesConfigurationSP DlgAnimaterionRenderer::getencoderConfiguration() const
{
if (!m_page->grpRenderOptions->isChecked()) {
return 0;
}
KisPropertiesConfigurationSP cfg = new KisPropertiesConfiguration();
return cfg;
}
void DlgAnimaterionRenderer::selectRenderType(int renderType)
{
// if (renderType >= m_configWidgets->size) return;
// Q_FOREACH(QWidget *w, m_configWidgets) {
// if (w) {
// w->setVisible(false);
// }
// }
// if (m_configWidgets[renterType]) {
// m_configWidgets[renderType]->setVisible(true);
// }
}
/*
* Copyright (c) 2016 Boudewijn Rempt <boud@valdyas.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef DLG_ANIMATIONRENDERERIMAGE
#define DLG_ANIMATIONRENDERERIMAGE
#include <KoDialog.h>
#include <kis_properties_configuration.h>
#include "ui_wdg_animationrenderer.h"
#include <QSharedPointer>
class KisImportExportFilter;
class WdgAnimaterionRenderer : public QWidget, public Ui::WdgAnimaterionRenderer
{
Q_OBJECT
public:
WdgAnimaterionRenderer(QWidget *parent)
: QWidget(parent)
{
setupUi(this);
}
};
class DlgAnimaterionRenderer: public KoDialog
{
Q_OBJECT
public:
DlgAnimaterionRenderer(QWidget *parent = 0);
~DlgAnimaterionRenderer();
KisPropertiesConfigurationSP getSequenceConfiguration() const;
KisPropertiesConfigurationSP getVideoConfiguration() const;
KisPropertiesConfigurationSP getencoderConfiguration() const;
private Q_SLOTS:
void selectRenderType(int renderType);
private:
WdgAnimaterionRenderer *m_page;
QList<QSharedPointer<KisImportExportFilter>> m_filters;
QList<QWidget> m_configWidgets;
};
#endif // DLG_ANIMATIONRENDERERIMAGE
{
"Id": "AnimationRenderer Plugin",
"Type": "Service",
"X-KDE-Library": "kritaanimationrenderer",
"X-KDE-ServiceTypes": [
"Krita/ViewPlugin"
],
"X-Krita-Version": "28"
}
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>WdgAnimaterionRenderer</class>
<widget class="QWidget" name="WdgAnimaterionRenderer">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>460</width>
<height>581</height>
</rect>
</property>
<property name="windowTitle">
<string>AnimationRenderer Image</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Image Sequence</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Base name:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="txtBasename"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Render location:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="KisFileNameRequester" name="dirRequester" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>First frame:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="intStart"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Last frame:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="intEnd"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Sequence starts with:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QSpinBox" name="sequenceStart"/>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Render</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Render as:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="cmbRenderType"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>File:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="KisFileNameRequester" name="videoFilename" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QGroupBox" name="grpRenderOptions">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Render Options</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QCheckBox" name="chkDeleteSequence">
<property name="text">
<string>Delete Sequence After Rendering</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KisFileNameRequester</class>
<extends>QWidget</extends>
<header>kis_file_name_requester.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
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