Beispiel #1
0
void AnimationDocker::setCanvas(KoCanvasBase * canvas)
{
    if(m_canvas == canvas)
        return;

    setEnabled(canvas != 0);

    if (m_canvas) {
        m_canvas->disconnectCanvasObserver(this);
        m_canvas->image()->disconnect(this);
        m_canvas->image()->animationInterface()->disconnect(this);
        m_canvas->animationPlayer()->disconnect(this);
    }

    m_canvas = dynamic_cast<KisCanvas2*>(canvas);

    if (m_canvas && m_canvas->image()) {
        KisImageAnimationInterface *animation = m_canvas->image()->animationInterface();
        {
            KisSignalsBlocker bloker(m_animationWidget->spinFromFrame,
                                     m_animationWidget->spinToFrame,
                                     m_animationWidget->intFramerate);

            m_animationWidget->spinFromFrame->setValue(animation->fullClipRange().start());
            m_animationWidget->spinToFrame->setValue(animation->fullClipRange().end());
            m_animationWidget->intFramerate->setValue(animation->framerate());
        }

        connect(animation, SIGNAL(sigTimeChanged(int)), this, SLOT(slotGlobalTimeChanged()));
        connect(m_canvas->animationPlayer(), SIGNAL(sigFrameChanged()), this, SLOT(slotGlobalTimeChanged()));
        connect(m_canvas->animationPlayer(), SIGNAL(sigPlaybackStopped()), this, SLOT(slotGlobalTimeChanged()));
        connect(m_canvas->animationPlayer(), SIGNAL(sigPlaybackStopped()), this, SLOT(updatePlayPauseIcon()));
        connect(m_canvas->animationPlayer(), SIGNAL(sigPlaybackStatisticsUpdated()), this, SLOT(updateDropFramesIcon()));
        connect(m_animationWidget->doublePlaySpeed,
                SIGNAL(valueChanged(double)),
                m_canvas->animationPlayer(),
                SLOT(slotUpdatePlaybackSpeed(double)));

        slotGlobalTimeChanged();
    }
Beispiel #2
0
void KisKraLoader::loadAnimationMetadata(const KoXmlElement &element, KisImageWSP image)
{
    QDomDocument qDom;
    KoXml::asQDomElement(qDom, element);
    QDomElement qElement = qDom.firstChildElement();

    float framerate;
    KisTimeRange range;
    int currentTime;

    KisImageAnimationInterface *animation = image->animationInterface();

    if (KisDomUtils::loadValue(qElement, "framerate", &framerate)) {
        animation->setFramerate(framerate);
    }

    if (KisDomUtils::loadValue(qElement, "range", &range)) {
        animation->setFullClipRange(range);
    }

    if (KisDomUtils::loadValue(qElement, "currentTime", &currentTime)) {
        animation->switchCurrentTimeAsync(currentTime);
    }
}
    int baseNumFrames() const {
        KisImageAnimationInterface *i = image->animationInterface();
        if (!i) return 1;

        return i->totalLength();
    }
Beispiel #4
0
KisImageBuilder_Result CSVSaver::encode(const QUrl &uri,const QString &filename)
{
    int idx;
    int start, end;
    KisNodeSP node;
    QByteArray ba;
    KisKeyframeSP keyframe;
    QVector<CSVLayerRecord*> layers;

    KisImageAnimationInterface *animation = m_image->animationInterface();

    //open the csv file for writing
    QFile f(uri.toLocalFile());
    if (!f.open(QIODevice::WriteOnly)) {
        return KisImageBuilder_RESULT_NOT_LOCAL;
    }

    QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));

    //DataStream instead of TextStream for correct line endings
    QDataStream stream(&f);

    QString path = filename;

    if (path.right(4).toUpper() == ".CSV")
        path = path.left(path.size() - 4);

    path.append(".frames");

    //create directory

    QDir dir(path);
    if (!dir.exists()) {
        dir.mkpath(".");
    }
    //according to the QT docs, the slash is a universal directory separator
    path.append("/");

    m_image->lock();
    node = m_image->rootLayer()->firstChild();

    //TODO: correct handling of the layer tree.
    //for now, only top level paint layers are saved

    idx = 0;

    while (node) {
        if (node->inherits("KisPaintLayer")) {
            KisPaintLayer* paintLayer = dynamic_cast<KisPaintLayer*>(node.data());
            CSVLayerRecord* layerRecord = new CSVLayerRecord();
            layers.prepend(layerRecord); //reverse order!

            layerRecord->name = paintLayer->name();
            layerRecord->name.replace(QRegExp("[\"\\r\\n]"), "_");

            if (layerRecord->name.isEmpty())
                layerRecord->name= QString("Unnamed-%1").arg(idx);

            layerRecord->visible = (paintLayer->visible()) ? 1 : 0;
            layerRecord->density = (float)(paintLayer->opacity()) / OPACITY_OPAQUE_U8;
            layerRecord->blending = convertToBlending(paintLayer->compositeOpId());
            layerRecord->layer = paintLayer;
            layerRecord->channel = paintLayer->projection()->keyframeChannel();
            layerRecord->last = "";
            layerRecord->frame = 0;
            idx++;
        }
        node = node->nextSibling();
    }

    KisTimeRange range = animation->fullClipRange();

    start = (range.isValid()) ? range.start() : 0;

    if (!range.isInfinite()) {
        end = range.end();

        if (end < start) end = start;
    } else {
        //undefined length, searching for the last keyframe
        end = start;

        for (idx = 0; idx < layers.size(); idx++) {
            keyframe = layers.at(idx)->channel->lastKeyframe();

            if ( (!keyframe.isNull()) && (keyframe->time() > end) )
                end = keyframe->time();
        }
    }

    //create temporary doc for exporting
    QScopedPointer<KisDocument> exportDoc(KisPart::instance()->createDocument());
    createTempImage(exportDoc.data());

    KisImageBuilder_Result retval= KisImageBuilder_RESULT_OK;

    if (!m_batchMode) {
        emit m_doc->statusBarMessage(i18n("Saving CSV file..."));
        emit m_doc->sigProgress(0);
        connect(m_doc, SIGNAL(sigProgressCanceled()), this, SLOT(cancel()));
    }
    int frame = start;
    int step = 0;

    do {
        qApp->processEvents();

        if (m_stop) {
            retval = KisImageBuilder_RESULT_CANCEL;
            break;
        }

        switch(step) {

        case 0 :    //first row
            if (f.write("UTF-8, TVPaint, \"CSV 1.0\"\r\n") < 0) {
                retval = KisImageBuilder_RESULT_FAILURE;
            }
            break;

        case 1 :    //scene header names
            if (f.write("Project Name, Width, Height, Frame Count, Layer Count, Frame Rate, Pixel Aspect Ratio, Field Mode\r\n") < 0) {
                retval = KisImageBuilder_RESULT_FAILURE;
            }
            break;

        case 2 :    //scene header values
            ba = QString("\"%1\", ").arg(m_image->objectName()).toUtf8();
            if (f.write(ba.data()) < 0) {
                retval = KisImageBuilder_RESULT_FAILURE;
                break;
            }
            ba = QString("%1, %2, ").arg(m_image->width()).arg(m_image->height()).toUtf8();
            if (f.write(ba.data()) < 0) {
                retval = KisImageBuilder_RESULT_FAILURE;
                break;
            }

            ba = QString("%1, %2, ").arg(end - start + 1).arg(layers.size()).toUtf8();
            if (f.write(ba.data()) < 0) {
                retval = KisImageBuilder_RESULT_FAILURE;
                break;
            }
            //the framerate is an integer here
            ba = QString("%1, ").arg((double)(animation->framerate()),0,'f',6).toUtf8();
            if (f.write(ba.data()) < 0) {
                retval = KisImageBuilder_RESULT_FAILURE;
                break;
            }
            ba = QString("%1, Progressive\r\n").arg((double)(m_image->xRes() / m_image->yRes()),0,'f',6).toUtf8();
            if (f.write(ba.data()) < 0) {
                retval = KisImageBuilder_RESULT_FAILURE;
                break;
            }
            break;

        case 3 :    //layer header values
            if (f.write("#Layers") < 0) {          //Layers
                retval = KisImageBuilder_RESULT_FAILURE;
                break;
            }

            for (idx = 0; idx < layers.size(); idx++) {
                ba = QString(", \"%1\"").arg(layers.at(idx)->name).toUtf8();
                if (f.write(ba.data()) < 0)
                    break;
            }
            break;

        case 4 :
            if (f.write("\r\n#Density") < 0) {     //Density
                retval = KisImageBuilder_RESULT_FAILURE;
                break;
            }
            for (idx = 0; idx < layers.size(); idx++) {
                ba = QString(", %1").arg((double)(layers.at(idx)->density), 0, 'f', 6).toUtf8();
                if (f.write(ba.data()) < 0)
                    break;
            }
            break;

        case 5 :
            if (f.write("\r\n#Blending") < 0) {     //Blending
                retval = KisImageBuilder_RESULT_FAILURE;
                break;
            }
            for (idx = 0; idx < layers.size(); idx++) {
                ba = QString(", \"%1\"").arg(layers.at(idx)->blending).toUtf8();
                if (f.write(ba.data()) < 0)
                    break;
            }
            break;

        case 6 :
            if (f.write("\r\n#Visible") < 0) {     //Visible
                retval = KisImageBuilder_RESULT_FAILURE;
                break;
            }
            for (idx = 0; idx < layers.size(); idx++) {
                ba = QString(", %1").arg(layers.at(idx)->visible).toUtf8();
                if (f.write(ba.data()) < 0)
                    break;
            }
            if (idx < layers.size()) {
                retval = KisImageBuilder_RESULT_FAILURE;
            }
            break;

        default :    //frames

            if (frame > end) {
                if (f.write("\r\n") < 0)
                    retval = KisImageBuilder_RESULT_FAILURE;

                step = 8;
                break;
            }

            ba = QString("\r\n#%1").arg(frame, 5, 10, QChar('0')).toUtf8();
            if (f.write(ba.data()) < 0) {
                retval = KisImageBuilder_RESULT_FAILURE;
                break;
            }

            for (idx = 0; idx < layers.size(); idx++) {
                CSVLayerRecord *layer = layers.at(idx);
                keyframe = layer->channel->keyframeAt(frame);

                if (!keyframe.isNull()) {
                    if (!m_batchMode) {
                        emit m_doc->sigProgress(((frame - start) * layers.size() + idx) * 100 /
                                                ((end - start) * layers.size()));
                    }
                    retval = getLayer(layer, exportDoc.data(), keyframe, path, frame, idx);

                    if (retval != KisImageBuilder_RESULT_OK)
                        break;
                }
                ba = QString(", \"%1\"").arg(layer->last).toUtf8();

                if (f.write(ba.data()) < 0)
                    break;
            }
            if (idx < layers.size())
                retval = KisImageBuilder_RESULT_FAILURE;

            frame++;
            step = 6; //keep step here
            break;
        }
        step++;
    } while((retval == KisImageBuilder_RESULT_OK) && (step < 8));

    m_image->unlock();

    qDeleteAll(layers);
    f.close();

    if (!m_batchMode) {
        disconnect(m_doc, SIGNAL(sigProgressCanceled()), this, SLOT(cancel()));
        emit m_doc->sigProgress(100);
        emit m_doc->clearStatusBarMessage();
    }
    QApplication::restoreOverrideCursor();
    return retval;
}