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; }
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(); }
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; }
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; }
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; }
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)); }
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); }
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; }