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();
    }
bool checkLayers(KisImageWSP image,
                 const QString &prefix)
{
    KisNodeSP layer1 = image->rootLayer()->firstChild();
    KisNodeSP layer2 = layer1->nextSibling();

    QVector<QImage> images(3);
    images[0] = image->projection()->convertToQImage(0, 0, 0, 300, 300);
    images[1] = layer1->paintDevice()->convertToQImage(0, 0, 0, 300, 300);
    images[2] = layer2->paintDevice()->convertToQImage(0, 0, 0, 300, 300);

    QVector<QString> names(3);
    names[0] = QString("applicator_") + prefix + "_projection.png";
    names[1] = QString("applicator_") + prefix + "_layer1.png";
    names[2] = QString("applicator_") + prefix + "_layer2.png";

    bool valid = true;
    for(int i = 0; i < 3; i++) {
        QImage ref(QString(FILES_DATA_DIR) + QDir::separator() +
                   "applicator" + QDir::separator() + names[i]);

        QPoint temp;

        if(!TestUtil::compareQImages(temp, ref, images[i], 1)) {
            qDebug() << "--- Wrong image:" << names[i];
            valid = false;
            images[i].save(QString(FILES_OUTPUT_DIR) + QDir::separator() + names[i]);
        }
    }

    return valid;
}
示例#3
0
    void rebuildLayerList(KisNodeSP layer = 0)
    {
        bool refreshingFromRoot = false;
        if (!image)
        {
            layers.clear();
            return;
        }
        if (layer == 0)
        {
            refreshingFromRoot = true;
            layers.clear();
            layer = image->rootLayer();
        }
        // implementation node: The root node is not a visible node, and so
        // is never added to the list of layers
        QList<KisNodeSP> children = layer->childNodes(layerClassNames(), KoProperties());
        if (children.count() == 0)
            return;
        for(quint32 i = children.count(); i > 0; --i)
        {
            layers << children.at(i-1);
            rebuildLayerList(children.at(i-1));
        }

        if (refreshingFromRoot)
            refreshLayerMovementAbilities();
    }
示例#4
0
QDomElement KisKraSaver::saveXML(QDomDocument& doc,  KisImageWSP image)
{
    QDomElement imageElement = doc.createElement("IMAGE"); // Legacy!

    Q_ASSERT(image);
    imageElement.setAttribute(NAME, m_d->imageName);
    imageElement.setAttribute(MIME, NATIVE_MIMETYPE);
    imageElement.setAttribute(WIDTH, image->width());
    imageElement.setAttribute(HEIGHT, image->height());
    imageElement.setAttribute(COLORSPACE_NAME, image->colorSpace()->id());
    imageElement.setAttribute(DESCRIPTION, m_d->doc->documentInfo()->aboutInfo("comment"));
    // XXX: Save profile as blob inside the image, instead of the product name.
    if (image->profile() && image->profile()-> valid()) {
        imageElement.setAttribute(PROFILE, image->profile()->name());
    }
    imageElement.setAttribute(X_RESOLUTION, image->xRes()*72.0);
    imageElement.setAttribute(Y_RESOLUTION, image->yRes()*72.0);

    quint32 count = 1; // We don't save the root layer, but it does count
    KisSaveXmlVisitor visitor(doc, imageElement, count, true);

    image->rootLayer()->accept(visitor);
    m_d->nodeFileNames = visitor.nodeFileNames();
    return imageElement;
}
示例#5
0
KisImageBuilder_Result CSVSaver::getLayer(CSVLayerRecord* layer, KisDocument* exportDoc, KisKeyframeSP keyframe, const QString &path, int frame, int idx)
{
    //render to the temp layer
    KisImageWSP image = exportDoc->image();
    KisPaintDeviceSP device = image->rootLayer()->firstChild()->projection();

    layer->channel->fetchFrame(keyframe, device);
    QRect bounds = device->exactBounds();

    if (bounds.isEmpty()) {
        layer->last = "";                   //empty frame
        return KisImageBuilder_RESULT_OK;
    }
    layer->last = QString("frame%1-%2.png").arg(idx + 1,5,10,QChar('0')).arg(frame,5,10,QChar('0'));

    QString filename = path;
    filename.append(layer->last);

    //save to PNG

    KisSequentialConstIterator it(device, image->bounds());
    const KoColorSpace* cs = device->colorSpace();

    bool isThereAlpha = false;
    do {
        if (cs->opacityU8(it.oldRawData()) != OPACITY_OPAQUE_U8) {
            isThereAlpha = true;
            break;
        }
    } while (it.nextPixel());

    if (!KisPNGConverter::isColorSpaceSupported(cs)) {
        device = new KisPaintDevice(*device.data());
        KUndo2Command *cmd= device->convertTo(KoColorSpaceRegistry::instance()->rgb8());
        delete cmd;
    }
    KisPNGOptions options;

    options.alpha = isThereAlpha;
    options.interlace = false;
    options.compression = 8;
    options.tryToSaveAsIndexed = false;
    options.transparencyFillColor = QColor(0,0,0);
    options.saveSRGBProfile = true;                 //TVPaint can use only sRGB
    options.forceSRGB = false;

    KisPNGConverter kpc(exportDoc);

    KisImageBuilder_Result result = kpc.buildFile(QUrl::fromLocalFile(filename), image->bounds(),
                                                  image->xRes(), image->yRes(), device,
                                                  image->beginAnnotations(), image->endAnnotations(),
                                                  options, (KisMetaData::Store* )0 );

    return result;
}
示例#6
0
bool KisKraSaver::saveBinaryData(KoStore* store, KisImageWSP image, const QString & uri, bool external)
{
    QString location;

    // Save the layers data
    quint32 count = 0;

    KisKraSaveVisitor visitor(image, store, count, m_d->imageName, m_d->nodeFileNames);

    if (external)
        visitor.setExternalUri(uri);

    image->rootLayer()->accept(visitor);
    // saving annotations
    // XXX this only saves EXIF and ICC info. This would probably need
    // a redesign of the dtd of the krita file to do this more generally correct
    // e.g. have <ANNOTATION> tags or so.
    KisAnnotationSP annotation = image->annotation("exif");
    if (annotation) {
        location = external ? QString::null : uri;
        location += m_d->imageName + EXIF_PATH;
        if (store->open(location)) {
            store->write(annotation->annotation());
            store->close();
        }
    }
    if (image->profile()) {
        const KoColorProfile *profile = image->profile();
        KisAnnotationSP annotation;
        if (profile) {
            QByteArray profileRawData = profile->rawData();
            if (!profileRawData.isEmpty()) {
                if (profile->type() == "icc") {
                    annotation = new KisAnnotation(ICC, profile->name(), profile->rawData());
                } else {
                    annotation = new KisAnnotation(PROFILE, profile->name(), profile->rawData());
                }
            }
        }

        if (annotation) {
            location = external ? QString::null : uri;
            location += m_d->imageName + ICC_PATH;
            if (store->open(location)) {
                store->write(annotation->annotation());
                store->close();
            }
        }
    }
    return true;
}
示例#7
0
void CSVSaver::createTempImage(KisDocument* exportDoc)
{
    exportDoc->setAutoSave(0);
    exportDoc->setOutputMimeType("image/png");
    exportDoc->setFileBatchMode(true);

    KisImageWSP exportImage = new KisImage(exportDoc->createUndoStore(),
                                           m_image->width(), m_image->height(), m_image->colorSpace(),
                                           QString());

    exportImage->setResolution(m_image->xRes(), m_image->yRes());
    exportDoc->setCurrentImage(exportImage);

    KisPaintLayer* paintLayer = new KisPaintLayer(exportImage, "paint device", OPACITY_OPAQUE_U8);
    exportImage->addNode(paintLayer, exportImage->rootLayer(), KisLayerSP(0));
}
示例#8
0
void KisKraLoader::loadBinaryData(KoStore * store, KisImageWSP image, const QString & uri, bool external)
{
    // icc profile: if present, this overrides the profile product name loaded in loadXML.
    QString location = external ? QString() : uri;
    location += m_d->imageName + ICC_PATH;
    if (store->hasFile(location)) {
        if (store->open(location)) {
            QByteArray data; data.resize(store->size());
            bool res = (store->read(data.data(), store->size()) > -1);
            store->close();
            if (res) {
                const KoColorProfile *profile = KoColorSpaceRegistry::instance()->createColorProfile(image->colorSpace()->colorModelId().id(), image->colorSpace()->colorDepthId().id(), data);
                if (profile && profile->valid()) {
                    res = image->assignImageProfile(profile);
                }
                if (!res) {
                    profile = KoColorSpaceRegistry::instance()->profileByName(KoColorSpaceRegistry::instance()->colorSpaceFactory(image->colorSpace()->id())->defaultProfile());
                    Q_ASSERT(profile && profile->valid());
                    image->assignImageProfile(profile);
                }
            }
        }
    }

    // Load the layers data: if there is a profile associated with a layer it will be set now.
    KisKraLoadVisitor visitor(image, store, m_d->layerFilenames, m_d->imageName, m_d->syntaxVersion);

    if (external) {
        visitor.setExternalUri(uri);
    }

    image->rootLayer()->accept(visitor);
    if (!visitor.errorMessages().isEmpty()) {
        m_d->errorMessages.append(visitor.errorMessages());
    }

    // annotations
    // exif
    location = external ? QString() : uri;
    location += m_d->imageName + EXIF_PATH;
    if (store->hasFile(location)) {
        QByteArray data;
        store->open(location);
        data = store->read(store->size());
        store->close();
        image->addAnnotation(KisAnnotationSP(new KisAnnotation("exif", "", data)));
    }


    // layer styles
    location = external ? QString() : uri;
    location += m_d->imageName + LAYER_STYLES_PATH;
    if (store->hasFile(location)) {
        KisPSDLayerStyleCollectionResource *collection =
            new KisPSDLayerStyleCollectionResource("Embedded Styles.asl");

        collection->setName(i18nc("Auto-generated layer style collection name for embedded styles (collection)", "<%1> (embedded)", m_d->imageName));

        KIS_ASSERT_RECOVER_NOOP(!collection->valid());

        store->open(location);
        {
            KoStoreDevice device(store);
            device.open(QIODevice::ReadOnly);

            /**
             * ASL loading code cannot work with non-sequential IO devices,
             * so convert the device beforehand!
             */
            QByteArray buf = device.readAll();
            QBuffer raDevice(&buf);
            raDevice.open(QIODevice::ReadOnly);
            collection->loadFromDevice(&raDevice);
        }
        store->close();

        if (collection->valid()) {
            KoResourceServer<KisPSDLayerStyleCollectionResource> *server = KisResourceServerProvider::instance()->layerStyleCollectionServer();
            server->addResource(collection, false);

            collection->assignAllLayerStyles(image->root());
        } else {
            warnKrita << "WARNING: Couldn't load layer styles library from .kra!";
            delete collection;
        }
    }

    if (m_d->document && m_d->document->documentInfo()->aboutInfo("title").isNull())
        m_d->document->documentInfo()->setAboutInfo("title", m_d->imageName);
    if (m_d->document && m_d->document->documentInfo()->aboutInfo("comment").isNull())
        m_d->document->documentInfo()->setAboutInfo("comment", m_d->imageComment);

    loadAssistants(store, uri, external);
}
示例#9
0
KisImageWSP KisKraLoader::loadXML(const KoXmlElement& element)
{
    QString attr;
    KisImageWSP image = 0;
    QString name;
    qint32 width;
    qint32 height;
    QString profileProductName;
    double xres;
    double yres;
    QString colorspacename;
    const KoColorSpace * cs;

    if ((attr = element.attribute(MIME)) == NATIVE_MIMETYPE) {

        if ((m_d->imageName = element.attribute(NAME)).isNull()) {
            m_d->errorMessages << i18n("Image does not have a name.");
            return KisImageWSP(0);
        }

        if ((attr = element.attribute(WIDTH)).isNull()) {
            m_d->errorMessages << i18n("Image does not specify a width.");
            return KisImageWSP(0);
        }
        width = attr.toInt();

        if ((attr = element.attribute(HEIGHT)).isNull()) {
            m_d->errorMessages << i18n("Image does not specify a height.");
            return KisImageWSP(0);
        }

        height = attr.toInt();

        m_d->imageComment = element.attribute(DESCRIPTION);

        xres = 100.0 / 72.0;
        if (!(attr = element.attribute(X_RESOLUTION)).isNull()) {
            if (attr.toDouble() > 1.0) {
                xres = attr.toDouble() / 72.0;
            }
        }

        yres = 100.0 / 72.0;
        if (!(attr = element.attribute(Y_RESOLUTION)).isNull()) {
            if (attr.toDouble() > 1.0) {
                yres = attr.toDouble() / 72.0;
            }
        }

        if ((colorspacename = element.attribute(COLORSPACE_NAME)).isNull()) {
            // An old file: take a reasonable default.
            // Krita didn't support anything else in those
            // days anyway.
            colorspacename = "RGBA";
        }

        profileProductName = element.attribute(PROFILE);
        // A hack for an old colorspacename
        convertColorSpaceNames(colorspacename, profileProductName);

        QString colorspaceModel = KoColorSpaceRegistry::instance()->colorSpaceColorModelId(colorspacename).id();
        QString colorspaceDepth = KoColorSpaceRegistry::instance()->colorSpaceColorDepthId(colorspacename).id();

        if (profileProductName.isNull()) {
            // no mention of profile so get default profile";
            cs = KoColorSpaceRegistry::instance()->colorSpace(colorspaceModel, colorspaceDepth, "");
        } else {
            cs = KoColorSpaceRegistry::instance()->colorSpace(colorspaceModel, colorspaceDepth, profileProductName);
        }

        if (cs == 0) {
            // try once more without the profile
            cs = KoColorSpaceRegistry::instance()->colorSpace(colorspaceModel, colorspaceDepth, "");
            if (cs == 0) {
                m_d->errorMessages << i18n("Image specifies an unsupported color model: %1.", colorspacename);
                return KisImageWSP(0);
            }
        }

        if (m_d->document) {
            image = new KisImage(m_d->document->createUndoStore(), width, height, cs, name);
        }
        else {
            image = new KisImage(0, width, height, cs, name);
        }
        image->setResolution(xres, yres);
        loadNodes(element, image, const_cast<KisGroupLayer*>(image->rootLayer().data()));

        KoXmlNode child;
        for (child = element.lastChild(); !child.isNull(); child = child.previousSibling()) {
            KoXmlElement e = child.toElement();
            if(e.tagName() == "ProjectionBackgroundColor") {
                if (e.hasAttribute("ColorData")) {
                    QByteArray colorData = QByteArray::fromBase64(e.attribute("ColorData").toLatin1());
                    KoColor color((const quint8*)colorData.data(), image->colorSpace());
                    image->setDefaultProjectionColor(color);
                }
            }

            if (e.tagName().toLower() == "animation") {
                loadAnimationMetadata(e, image);
            }
        }

        for (child = element.lastChild(); !child.isNull(); child = child.previousSibling()) {
            KoXmlElement e = child.toElement();
            if(e.tagName() == "compositions") {
                loadCompositions(e, image);
            }
        }
    }
    KoXmlNode child;
    for (child = element.lastChild(); !child.isNull(); child = child.previousSibling()) {
        KoXmlElement e = child.toElement();
        if (e.tagName() == "assistants") {
            loadAssistantsList(e);
        }
    }
    return image;
}