Esempio n. 1
0
    Private(KisDocument *document, int fromTime, int toTime)
        : document(document),
          image(document->image()),
          firstFrame(fromTime),
          lastFrame(toTime),
          tmpDoc(KisPart::instance()->createDocument()),
          exporting(false),
          batchMode(false)
    {
        tmpDoc->setAutoSave(0);

        tmpImage = new KisImage(tmpDoc->createUndoStore(),
            image->bounds().width(),
            image->bounds().height(),
            image->colorSpace(),
            QString());

        tmpImage->setResolution(image->xRes(), image->yRes());
        tmpDoc->setCurrentImage(tmpImage);

        KisPaintLayer* paintLayer = new KisPaintLayer(tmpImage, "paint device", 255);
        tmpImage->addNode(paintLayer, tmpImage->rootLayer(), KisLayerSP(0));

        tmpDevice = paintLayer->paintDevice();
    }
Esempio n. 2
0
void KritaShape::tryLoadFromImageData(KoImageData *data)
{

    if (data == 0)
        return;

    // TODO maybe we want to use the image rawData for that
    QImage image = data->image();

    if (image.isNull())
        return;

    delete m_d->doc;

    m_d->doc = new KisDoc2(0, 0, false);
    connect(m_d->doc, SIGNAL(sigLoadingFinished()), this, SLOT(slotLoadingFinished()));

    // Create an empty image
    KisImageSP img = m_d->doc->newImage(i18n("Converted from KoImageData"), image.width(), image.height(), 0);

    // Convert the QImage to a paint device
    KisPaintLayer * layer = dynamic_cast<KisPaintLayer*>(img->root()->firstChild().data());
    if (layer)
        layer->paintDevice()->convertFromQImage(image, "", 0, 0);

    // emits sigLoadingFinished
    m_d->doc->setCurrentImage(img);
}
Esempio n. 3
0
bool ChannelModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
    if (m_currentLayer.isValid() && index.isValid())
    {
        QList<KoChannelInfo*> channels = m_currentLayer->colorSpace()->channels();
        int channelIndex = KoChannelInfo::displayPositionToChannelIndex(index.row(), channels);
        
        if (role == Qt::CheckStateRole) {
            Q_ASSERT(index.row() < rowCount());
            Q_ASSERT(index.column() < columnCount());
            
            if (index.column() == 0) {
                QBitArray flags = m_currentLayer->channelFlags();

                flags = flags.isEmpty() ? m_currentLayer->colorSpace()->channelFlags(true, true) : flags;
                flags.setBit(channelIndex, value.toInt() == Qt::Checked);
                m_currentLayer->setChannelFlags(flags);
            }
            else { //if (index.column() == 1)
                KisPaintLayer* paintLayer = dynamic_cast<KisPaintLayer*>(m_currentLayer.data());
                QBitArray      flags      = paintLayer->channelLockFlags();
                flags = flags.isEmpty() ? m_currentLayer->colorSpace()->channelFlags(true, true) : flags;
                flags.setBit(channelIndex, value.toInt() == Qt::Unchecked);
                paintLayer->setChannelLockFlags(flags);
            }
            
            m_currentLayer->setDirty();
            return true;
        }
    }
    return false;
}
Esempio n. 4
0
QBitArray KisResourcesSnapshot::channelLockFlags() const
{
    QBitArray channelFlags;
    KisPaintLayer *paintLayer;
    if ((paintLayer = dynamic_cast<KisPaintLayer*>(m_d->currentNode.data()))) {

        channelFlags = paintLayer->channelLockFlags();
        if (m_d->globalAlphaLock) {
            if (channelFlags.isEmpty()) {
                channelFlags = paintLayer->colorSpace()->channelFlags(true, true);
            }

            channelFlags &= paintLayer->colorSpace()->channelFlags(true, false);
        }
    }
    return channelFlags;
}
Esempio n. 5
0
void Imagesplit::saveAsImage(QRect imgSize, QString mimeType, QUrl url)
{
    KisImageWSP image = m_view->image();

    KisDocument *d = KisPart::instance()->createDocument();
    d->prepareForImport();

    KisImageWSP dst = new KisImage(d->createUndoStore(), imgSize.width(), imgSize.height(), image->colorSpace(), image->objectName());
    dst->setResolution(image->xRes(), image->yRes());
    d->setCurrentImage(dst);

    KisPaintLayer* paintLayer = new KisPaintLayer(dst, dst->nextLayerName(), 255);
    KisPainter gc(paintLayer->paintDevice());
    gc.bitBlt(QPoint(0, 0), image->projection(), imgSize);

    dst->addNode(paintLayer, KisNodeSP(0));
    dst->refreshGraph();
    d->setOutputMimeType(mimeType.toLatin1());
    d->exportDocument(url);

    delete d;
}
Esempio n. 6
0
KisNodeSP KisKraLoader::loadNode(const KoXmlElement& element, KisImageWSP image, KisNodeSP parent)
{
    // Nota bene: If you add new properties to layers, you should
    // ALWAYS define a default value in case the property is not
    // present in the layer definition: this helps a LOT with backward
    // compatibility.
    QString name = element.attribute(NAME, "No Name");

    QUuid id = QUuid(element.attribute(UUID, QUuid().toString()));

    qint32 x = element.attribute(X, "0").toInt();
    qint32 y = element.attribute(Y, "0").toInt();

    qint32 opacity = element.attribute(OPACITY, QString::number(OPACITY_OPAQUE_U8)).toInt();
    if (opacity < OPACITY_TRANSPARENT_U8) opacity = OPACITY_TRANSPARENT_U8;
    if (opacity > OPACITY_OPAQUE_U8) opacity = OPACITY_OPAQUE_U8;

    const KoColorSpace* colorSpace = 0;
    if ((element.attribute(COLORSPACE_NAME)).isNull()) {
        dbgFile << "No attribute color space for layer: " << name;
        colorSpace = image->colorSpace();
    }
    else {
        QString colorspacename = element.attribute(COLORSPACE_NAME);
        QString profileProductName;

        convertColorSpaceNames(colorspacename, profileProductName);

        QString colorspaceModel = KoColorSpaceRegistry::instance()->colorSpaceColorModelId(colorspacename).id();
        QString colorspaceDepth = KoColorSpaceRegistry::instance()->colorSpaceColorDepthId(colorspacename).id();
        dbgFile << "Searching color space: " << colorspacename << colorspaceModel << colorspaceDepth << " for layer: " << name;
        // use default profile - it will be replaced later in completeLoading

        colorSpace = KoColorSpaceRegistry::instance()->colorSpace(colorspaceModel, colorspaceDepth, "");
        dbgFile << "found colorspace" << colorSpace;
        if (!colorSpace) {
            m_d->errorMessages << i18n("Layer %1 specifies an unsupported color model: %2.", name, colorspacename);
            return 0;
        }
    }

    bool visible = element.attribute(VISIBLE, "1") == "0" ? false : true;
    bool locked = element.attribute(LOCKED, "0") == "0" ? false : true;
    bool collapsed = element.attribute(COLLAPSED, "0") == "0" ? false : true;

    // Now find out the layer type and do specific handling
    QString nodeType;

    if (m_d->syntaxVersion == 1) {
        nodeType = element.attribute("layertype");
        if (nodeType.isEmpty()) {
            nodeType = PAINT_LAYER;
        }
    }
    else {
        nodeType = element.attribute(NODE_TYPE);
    }

    if (nodeType.isEmpty()) {
        m_d->errorMessages << i18n("Layer %1 has an unsupported type.", name);
        return 0;
    }


    KisNodeSP node = 0;

    if (nodeType == PAINT_LAYER)
        node = loadPaintLayer(element, image, name, colorSpace, opacity);
    else if (nodeType == GROUP_LAYER)
        node = loadGroupLayer(element, image, name, colorSpace, opacity);
    else if (nodeType == ADJUSTMENT_LAYER)
        node = loadAdjustmentLayer(element, image, name, colorSpace, opacity);
    else if (nodeType == SHAPE_LAYER)
        node = loadShapeLayer(element, image, name, colorSpace, opacity);
    else if (nodeType == GENERATOR_LAYER)
        node = loadGeneratorLayer(element, image, name, colorSpace, opacity);
    else if (nodeType == CLONE_LAYER)
        node = loadCloneLayer(element, image, name, colorSpace, opacity);
    else if (nodeType == FILTER_MASK)
        node = loadFilterMask(element, parent);
    else if (nodeType == TRANSFORM_MASK)
        node = loadTransformMask(element, parent);
    else if (nodeType == TRANSPARENCY_MASK)
        node = loadTransparencyMask(element, parent);
    else if (nodeType == SELECTION_MASK)
        node = loadSelectionMask(image, element, parent);
    else if (nodeType == FILE_LAYER) {
        node = loadFileLayer(element, image, name, opacity);
    }
    else {
        m_d->errorMessages << i18n("Layer %1 has an unsupported type: %2.", name, nodeType);
        return 0;
    }

    // Loading the node went wrong. Return empty node and leave to
    // upstream to complain to the user
    if (!node) {
        m_d->errorMessages << i18n("Failure loading layer %1 of type: %2.", name, nodeType);
        return 0;
    }

    node->setVisible(visible, true);
    node->setUserLocked(locked);
    node->setCollapsed(collapsed);
    node->setX(x);
    node->setY(y);
    node->setName(name);

    if (! id.isNull())          // if no uuid in file, new one has been generated already
        node->setUuid(id);

    if (node->inherits("KisLayer")) {
        KisLayer* layer           = qobject_cast<KisLayer*>(node.data());
        QBitArray channelFlags    = stringToFlags(element.attribute(CHANNEL_FLAGS, ""), colorSpace->channelCount());
        QString   compositeOpName = element.attribute(COMPOSITE_OP, "normal");

        layer->setChannelFlags(channelFlags);
        layer->setCompositeOpId(compositeOpName);

        if (element.hasAttribute(LAYER_STYLE_UUID)) {
            QString uuidString = element.attribute(LAYER_STYLE_UUID);
            QUuid uuid(uuidString);
            if (!uuid.isNull()) {
                KisPSDLayerStyleSP dumbLayerStyle(new KisPSDLayerStyle());
                dumbLayerStyle->setUuid(uuid);
                layer->setLayerStyle(dumbLayerStyle);
            } else {
                warnKrita << "WARNING: Layer style for layer" << layer->name() << "contains invalid UUID" << uuidString;
            }
        }
    }

    if (node->inherits("KisGroupLayer")) {
        if (element.hasAttribute(PASS_THROUGH_MODE)) {
            bool value = element.attribute(PASS_THROUGH_MODE, "0") != "0";

            KisGroupLayer *group = qobject_cast<KisGroupLayer*>(node.data());
            group->setPassThroughMode(value);
        }
    }

    if (node->inherits("KisPaintLayer")) {
        KisPaintLayer* layer            = qobject_cast<KisPaintLayer*>(node.data());
        QBitArray      channelLockFlags = stringToFlags(element.attribute(CHANNEL_LOCK_FLAGS, ""), colorSpace->channelCount());
        layer->setChannelLockFlags(channelLockFlags);

        bool onionEnabled = element.attribute(ONION_SKIN_ENABLED, "0") == "0" ? false : true;
        layer->setOnionSkinEnabled(onionEnabled);

        bool timelineEnabled = element.attribute(VISIBLE_IN_TIMELINE, "0") == "0" ? false : true;
        layer->setUseInTimeline(timelineEnabled);
    }

    if (element.attribute(FILE_NAME).isNull()) {
        m_d->layerFilenames[node.data()] = name;
    }
    else {
        m_d->layerFilenames[node.data()] = element.attribute(FILE_NAME);
    }

    if (element.hasAttribute("selected") && element.attribute("selected") == "true")  {
        m_d->selectedNodes.append(node);
    }

    if (element.hasAttribute(KEYFRAME_FILE)) {
        node->enableAnimation();
        m_d->keyframeFilenames.insert(node.data(), element.attribute(KEYFRAME_FILE));
    }

    return node;
}
Esempio n. 7
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;
}