diff --git a/plugins/impex/jpeg/kis_jpeg_export.cc b/plugins/impex/jpeg/kis_jpeg_export.cc index 4e75727076..6c89fa127f 100644 --- a/plugins/impex/jpeg/kis_jpeg_export.cc +++ b/plugins/impex/jpeg/kis_jpeg_export.cc @@ -1,262 +1,288 @@ /* * Copyright (c) 2005 Cyrille Berger * * 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 "kis_jpeg_export.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kis_jpeg_converter.h" #include class KisExternalLayer; K_PLUGIN_FACTORY_WITH_JSON(KisJPEGExportFactory, "krita_jpeg_export.json", registerPlugin();) +// TODO: duplicated in kis_png_export.cc, move to KisPropertiesConfiguration? +static QColor getConfigurationStringAsQColor(const KisPropertiesConfigurationSP cfg, const QString& property, const QColor& default_color) +{ + QStringList components = cfg->getString(property, "").split(','); + + int num_components = components.size(); + if (num_components < 3 || num_components > 4) + return default_color; + + bool ok; + int rgba[4] = {0, 0, 0, 255}; + for( int i = 0; i < num_components; ++i) { + rgba[i] = components[i].toInt(&ok); + if(!ok) + return default_color; + } + + switch (num_components) { + case 3: + return QColor(rgba[0], rgba[1], rgba[2]); + case 4: + return QColor(rgba[0], rgba[1], rgba[2], rgba[3]); + default: + return default_color; + } +} + KisJPEGExport::KisJPEGExport(QObject *parent, const QVariantList &) : KisImportExportFilter(parent) { } KisJPEGExport::~KisJPEGExport() { } KisImportExportFilter::ConversionStatus KisJPEGExport::convert(const QByteArray& from, const QByteArray& to, KisPropertiesConfigurationSP configuration) { dbgFile << "JPEG export! From:" << from << ", To:" << to << ""; if (from != "application/x-krita") return KisImportExportFilter::NotImplemented; KisDocument *input = inputDocument(); if (!input) return KisImportExportFilter::NoDocumentCreated; KisImageSP image = input->savingImage(); Q_CHECK_PTR(image); KoDialog kdb; kdb.setWindowTitle(i18n("JPEG Export Options")); kdb.setButtons(KoDialog::Ok | KoDialog::Cancel); KisConfigWidget *wdg = createConfigurationWidget(&kdb, from, to); kdb.setMainWidget(wdg); kdb.resize(kdb.minimumSize()); // If a configuration object was passed to the convert method, we use that, otherwise we load from the settings KisPropertiesConfigurationSP cfg(new KisPropertiesConfiguration()); if (configuration) { cfg->fromXML(configuration->toXML()); } else { cfg = lastSavedConfiguration(from, to); } // An extra option to pass to the config widget to set the state correctly, this isn't saved const KoColorSpace* cs = image->projection()->colorSpace(); bool sRGB = cs->profile()->name().contains(QLatin1String("srgb"), Qt::CaseInsensitive); cfg->setProperty("is_sRGB", sRGB); wdg->setConfiguration(cfg); QApplication::restoreOverrideCursor(); if (!getBatchMode()) { if (kdb.exec() == QDialog::Rejected) { return KisImportExportFilter::UserCancelled; } cfg = wdg->configuration(); KisConfig().setExportConfiguration("JPEG", *cfg.data()); } KisJPEGOptions options; options.progressive = cfg->getBool("progressive", false); options.quality = cfg->getInt("quality", 80); options.forceSRGB = cfg->getBool("forceSRGB", false); options.saveProfile = cfg->getBool("saveProfile", true); options.optimize = cfg->getBool("optimize", true); options.smooth = cfg->getInt("smoothing", 0); options.baseLineJPEG = cfg->getBool("baseline", true); options.subsampling = cfg->getInt("subsampling", 0); options.exif = cfg->getBool("exif", true); options.iptc = cfg->getBool("iptc", true); options.xmp = cfg->getBool("xmp", true); - options.transparencyFillColor = cfg->getColor("transparencyFillcolor").toQColor(); + options.transparencyFillColor = getConfigurationStringAsQColor(cfg, "transparencyFillcolor", Qt::white); KisMetaData::FilterRegistryModel m; m.setEnabledFilters(cfg->getString("filters").split(",")); options.filters = m.enabledFilters(); QString filename = outputFile(); if (filename.isEmpty()) return KisImportExportFilter::FileNotFound; KisPaintDeviceSP pd = new KisPaintDevice(*image->projection()); KisJPEGConverter kpc(input, getBatchMode()); KisPaintLayerSP l = new KisPaintLayer(image, "projection", OPACITY_OPAQUE_U8, pd); vKisAnnotationSP_it beginIt = image->beginAnnotations(); vKisAnnotationSP_it endIt = image->endAnnotations(); KisImageBuilder_Result res; KisExifInfoVisitor eIV; eIV.visit(image->rootLayer().data()); KisMetaData::Store* eI = 0; if (eIV.countPaintLayer() == 1) eI = eIV.exifInfo(); if (eI) { KisMetaData::Store* copy = new KisMetaData::Store(*eI); eI = copy; } if ((res = kpc.buildFile(filename, l, beginIt, endIt, options, eI)) == KisImageBuilder_RESULT_OK) { dbgFile << "success !"; delete eI; return KisImportExportFilter::OK; } delete eI; dbgFile << " Result =" << res; return KisImportExportFilter::InternalError; } KisPropertiesConfigurationSP KisJPEGExport::defaultConfiguration(const QByteArray &/*from*/, const QByteArray &/*to*/) const { KisPropertiesConfigurationSP cfg = new KisPropertiesConfiguration(); cfg->setProperty("progressive", false); cfg->setProperty("quality", 80); cfg->setProperty("forceSRGB", false); cfg->setProperty("saveProfile", true); cfg->setProperty("optimize", true); cfg->setProperty("smoothing", 0); cfg->setProperty("baseline", true); cfg->setProperty("subsampling", 0); cfg->setProperty("exif", true); cfg->setProperty("iptc", true); cfg->setProperty("xmp", true); cfg->setProperty("transparencyFillcolor", QString("255,255,255")); cfg->setProperty("filters", ""); return cfg; } KisPropertiesConfigurationSP KisJPEGExport::lastSavedConfiguration(const QByteArray &from, const QByteArray &to) const { KisPropertiesConfigurationSP cfg = defaultConfiguration(from, to); QString filterConfig = KisConfig().exportConfiguration("JPEG"); cfg->fromXML(filterConfig, false); return cfg; } KisConfigWidget *KisJPEGExport::createConfigurationWidget(QWidget *parent, const QByteArray &/*from*/, const QByteArray &/*to*/) const { return new KisWdgOptionsJPEG(parent); } KisWdgOptionsJPEG::KisWdgOptionsJPEG(QWidget *parent) : KisConfigWidget(parent) { setupUi(this); metaDataFilters->setModel(&m_filterRegistryModel); qualityLevel->setRange(0, 100, 0); qualityLevel->setSuffix("%"); smoothLevel->setRange(0, 100, 0); smoothLevel->setSuffix("%"); } void KisWdgOptionsJPEG::setConfiguration(const KisPropertiesConfigurationSP cfg) { progressive->setChecked(cfg->getBool("progressive", false)); qualityLevel->setValue(cfg->getInt("quality", 80)); optimize->setChecked(cfg->getBool("optimize", true)); smoothLevel->setValue(cfg->getInt("smoothing", 0)); baseLineJPEG->setChecked(cfg->getBool("baseline", true)); subsampling->setCurrentIndex(cfg->getInt("subsampling", 0)); exif->setChecked(cfg->getBool("exif", true)); iptc->setChecked(cfg->getBool("iptc", true)); xmp->setChecked(cfg->getBool("xmp", true)); chkForceSRGB->setVisible(cfg->getBool("is_sRGB")); chkForceSRGB->setChecked(cfg->getBool("forceSRGB", false)); chkSaveProfile->setChecked(cfg->getBool("saveProfile", true)); - QStringList rgb = cfg->getString("transparencyFillcolor", "255,255,255").split(','); KoColor background(KoColorSpaceRegistry::instance()->rgb8()); background.fromQColor(Qt::white); bnTransparencyFillColor->setDefaultColor(background); - background.fromQColor(QColor(rgb[0].toInt(), rgb[1].toInt(), rgb[2].toInt())); + background.fromQColor(getConfigurationStringAsQColor(cfg, "transparencyFillcolor", Qt::white)); bnTransparencyFillColor->setColor(background); m_filterRegistryModel.setEnabledFilters(cfg->getString("filters").split(',')); } KisPropertiesConfigurationSP KisWdgOptionsJPEG::configuration() const { KisPropertiesConfigurationSP cfg = new KisPropertiesConfiguration(); cfg->setProperty("progressive", progressive->isChecked()); cfg->setProperty("quality", (int)qualityLevel->value()); cfg->setProperty("forceSRGB", chkForceSRGB->isChecked()); cfg->setProperty("saveProfile", chkSaveProfile->isChecked()); cfg->setProperty("optimize", optimize->isChecked()); cfg->setProperty("smoothing", (int)smoothLevel->value()); cfg->setProperty("baseline", baseLineJPEG->isChecked()); cfg->setProperty("subsampling", subsampling->currentIndex()); cfg->setProperty("exif", exif->isChecked()); cfg->setProperty("iptc", iptc->isChecked()); cfg->setProperty("xmp", xmp->isChecked()); QColor c = bnTransparencyFillColor->color().toQColor(); cfg->setProperty("transparencyFillcolor", QString("%1,%2,%3").arg(c.red()).arg(c.green()).arg(c.blue())); QString enabledFilters; Q_FOREACH (const KisMetaData::Filter* filter, m_filterRegistryModel.enabledFilters()) { enabledFilters = enabledFilters + filter->id() + ','; } cfg->setProperty("filters", enabledFilters); return cfg; } #include diff --git a/plugins/impex/png/kis_png_export.cc b/plugins/impex/png/kis_png_export.cc index c333bf1980..c6d1b48e72 100644 --- a/plugins/impex/png/kis_png_export.cc +++ b/plugins/impex/png/kis_png_export.cc @@ -1,289 +1,314 @@ /* * Copyright (c) 2005 Cyrille Berger * * 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 "kis_png_export.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kis_png_converter.h" #include K_PLUGIN_FACTORY_WITH_JSON(KisPNGExportFactory, "krita_png_export.json", registerPlugin();) +static QColor getConfigurationStringAsQColor(const KisPropertiesConfigurationSP cfg, const QString& property, const QColor& default_color) +{ + QStringList components = cfg->getString(property, "").split(','); + + int num_components = components.size(); + if (num_components < 3 || num_components > 4) + return default_color; + + bool ok; + int rgba[4] = {0, 0, 0, 255}; + for( int i = 0; i < num_components; ++i) { + rgba[i] = components[i].toInt(&ok); + if(!ok) + return default_color; + } + + switch (num_components) { + case 3: + return QColor(rgba[0], rgba[1], rgba[2]); + case 4: + return QColor(rgba[0], rgba[1], rgba[2], rgba[3]); + default: + return default_color; + } +} + KisPNGExport::KisPNGExport(QObject *parent, const QVariantList &) : KisImportExportFilter(parent) { } KisPNGExport::~KisPNGExport() { } bool hasVisibleWidgets() { QWidgetList wl = QApplication::allWidgets(); Q_FOREACH (QWidget* w, wl) { if (w->isVisible() && strcmp(w->metaObject()->className(), "QDesktopWidget")) { dbgFile << "Widget " << w << " " << w->objectName() << " " << w->metaObject()->className() << " is visible"; return true; } } return false; } KisImportExportFilter::ConversionStatus KisPNGExport::convert(const QByteArray& from, const QByteArray& to, KisPropertiesConfigurationSP configuration) { dbgFile << "Png export! From:" << from << ", To:" << to << ""; KisDocument *input = inputDocument(); QString filename = outputFile(); if (!input) return KisImportExportFilter::NoDocumentCreated; if (filename.isEmpty()) return KisImportExportFilter::FileNotFound; if (from != "application/x-krita") return KisImportExportFilter::NotImplemented; KisImageSP image = input->savingImage(); KisPaintDeviceSP pd; pd = new KisPaintDevice(*image->projection()); KisPaintLayerSP l = new KisPaintLayer(image, "projection", OPACITY_OPAQUE_U8, pd); if (!KisPNGConverter::isColorSpaceSupported(pd->colorSpace())) { if (!getBatchMode()) { qApp->setOverrideCursor(Qt::ArrowCursor); QMessageBox::warning(0, i18nc("@title:window", "Krita PNG Export"), i18n("You can only save 8 and 16 bits integer/channel grayscale and RGB images to PNG. Your image will be saved as 8 bits/channel RGB.")); qApp->restoreOverrideCursor(); } } KisSequentialConstIterator it(l->paintDevice(), image->bounds()); const KoColorSpace* cs = l->paintDevice()->colorSpace(); KisPNGOptions options; bool isThereAlpha = false; KisPropertiesConfigurationSP cfg = defaultConfiguration(); do { if (cs->opacityU8(it.oldRawData()) != OPACITY_OPAQUE_U8) { isThereAlpha = true; break; } } while (it.nextPixel()); if (!qApp->applicationName().toLower().contains("test")) { KoDialog kdb; kdb.setCaption(i18n("PNG Export Options")); kdb.setButtons(KoDialog::Ok | KoDialog::Cancel); KisConfigWidget *wdg = createConfigurationWidget(&kdb, from, to); kdb.setMainWidget(wdg); // If a configuration object was passed to the convert method, we use that, otherwise we load from the settings if (configuration) { cfg->fromXML(configuration->toXML()); } else { cfg = lastSavedConfiguration(from, to); } cfg->setProperty("ColorModelID", cs->colorModelId().id()); bool sRGB = (cs->profile()->name().contains(QLatin1String("srgb"), Qt::CaseInsensitive) && !cs->profile()->name().contains(QLatin1String("g10"))); cfg->setProperty("sRGB", sRGB); cfg->setProperty("isThereAlpha", isThereAlpha); wdg->setConfiguration(cfg); QApplication::restoreOverrideCursor(); if (hasVisibleWidgets()) { if (!getBatchMode()) { if (kdb.exec() == QDialog::Rejected) { return KisImportExportFilter::UserCancelled; } cfg = wdg->configuration(); KisConfig().setExportConfiguration("PNG", *cfg.data()); } } } options.alpha = cfg->getBool("alpha", true); options.interlace = cfg->getBool("interlaced", false); options.compression = cfg->getInt("compression", 0); options.tryToSaveAsIndexed = cfg->getBool("indexed", false); - options.transparencyFillColor = cfg->getColor("transparencyFillColor").toQColor(); + options.transparencyFillColor = getConfigurationStringAsQColor(cfg, "transparencyFillcolor", Qt::white); options.saveSRGBProfile = cfg->getBool("saveSRGBProfile", false); options.forceSRGB = cfg->getBool("forceSRGB", true); KisPNGConverter kpc(input); vKisAnnotationSP_it beginIt = image->beginAnnotations(); vKisAnnotationSP_it endIt = image->endAnnotations(); KisImageBuilder_Result res; KisExifInfoVisitor eIV; eIV.visit(image->rootLayer().data()); KisMetaData::Store* eI = 0; if (eIV.countPaintLayer() == 1) eI = eIV.exifInfo(); if (eI) { KisMetaData::Store* copy = new KisMetaData::Store(*eI); eI = copy; } if ((res = kpc.buildFile(filename, image->bounds(), image->xRes(), image->yRes(), l->paintDevice(), beginIt, endIt, options, eI)) == KisImageBuilder_RESULT_OK) { dbgFile << "success !"; delete eI; return KisImportExportFilter::OK; } delete eI; dbgFile << " Result =" << res; return KisImportExportFilter::InternalError; } KisPropertiesConfigurationSP KisPNGExport::defaultConfiguration(const QByteArray &, const QByteArray &) const { KisPropertiesConfigurationSP cfg = new KisPropertiesConfiguration(); cfg->setProperty("alpha", true); cfg->setProperty("indexed", false); cfg->setProperty("compression", 3); cfg->setProperty("interlaced", false); cfg->setProperty("transparencyFillcolor", QString("255,255,255")); cfg->setProperty("saveSRGBProfile", false); cfg->setProperty("forceSRGB", true); return cfg; } KisPropertiesConfigurationSP KisPNGExport::lastSavedConfiguration(const QByteArray &from, const QByteArray &to) const { QString filterConfig = KisConfig().exportConfiguration("PNG"); KisPropertiesConfigurationSP cfg = defaultConfiguration(from, to); cfg->fromXML(filterConfig, false); return cfg; } KisConfigWidget *KisPNGExport::createConfigurationWidget(QWidget *parent, const QByteArray &, const QByteArray &) const { return new KisWdgOptionsPNG(parent); } void KisWdgOptionsPNG::setConfiguration(const KisPropertiesConfigurationSP cfg) { bool isThereAlpha = cfg->getBool("isThereAlpha"); - alpha->setChecked(cfg->getBool("alpha", isThereAlpha)); + alpha->setChecked(cfg->getBool("alpha", isThereAlpha) && isThereAlpha); + alpha->setEnabled(isThereAlpha); + + bnTransparencyFillColor->setEnabled(!alpha->isChecked()); if (cfg->getString("ColorModelID") == RGBAColorModelID.id()) { tryToSaveAsIndexed->setVisible(true); if (alpha->isChecked()) { tryToSaveAsIndexed->setChecked(false); } else { tryToSaveAsIndexed->setChecked(cfg->getBool("indexed", false)); } } else { tryToSaveAsIndexed->setVisible(false); } interlacing->setChecked(cfg->getBool("interlaced", false)); compressionLevel->setValue(cfg->getInt("compression", 3)); compressionLevel->setRange(1, 9 , 0); - alpha->setEnabled(isThereAlpha); tryToSaveAsIndexed->setVisible(!isThereAlpha); - bnTransparencyFillColor->setEnabled(!alpha->isChecked()); - bool sRGB = cfg->getBool("sRGB", false); chkSRGB->setEnabled(sRGB); chkSRGB->setChecked(cfg->getBool("saveSRGBProfile", true)); chkForceSRGB->setEnabled(!sRGB); chkForceSRGB->setChecked(cfg->getBool("forceSRGB", false)); - QStringList rgb = cfg->getString("transparencyFillcolor", "0,0,0").split(','); KoColor c(KoColorSpaceRegistry::instance()->rgb8()); c.fromQColor(Qt::white); bnTransparencyFillColor->setDefaultColor(c); - c.fromQColor(QColor(rgb[0].toInt(), rgb[1].toInt(), rgb[2].toInt())); + c.fromQColor(getConfigurationStringAsQColor(cfg, "transparencyFillcolor", Qt::white)); bnTransparencyFillColor->setColor(c); } KisPropertiesConfigurationSP KisWdgOptionsPNG::configuration() const { KisPropertiesConfigurationSP cfg(new KisPropertiesConfiguration()); bool alpha = this->alpha->isChecked(); bool interlace = interlacing->isChecked(); int compression = (int)compressionLevel->value(); bool tryToSaveAsIndexed = this->tryToSaveAsIndexed->isChecked(); QColor c = bnTransparencyFillColor->color().toQColor(); bool saveSRGB = chkSRGB->isChecked(); bool forceSRGB = chkForceSRGB->isChecked(); cfg->setProperty("alpha", alpha); cfg->setProperty("indexed", tryToSaveAsIndexed); cfg->setProperty("compression", compression); cfg->setProperty("interlaced", interlace); cfg->setProperty("transparencyFillcolor", QString("%1,%2,%3").arg(c.red()).arg(c.green()).arg(c.blue())); cfg->setProperty("saveSRGBProfile", saveSRGB); cfg->setProperty("forceSRGB", forceSRGB); return cfg; } void KisWdgOptionsPNG::on_alpha_toggled(bool checked) { bnTransparencyFillColor->setEnabled(!checked); } #include "kis_png_export.moc" diff --git a/plugins/impex/png/kis_wdg_options_png.ui b/plugins/impex/png/kis_wdg_options_png.ui index 405c28ee77..a5405291d3 100644 --- a/plugins/impex/png/kis_wdg_options_png.ui +++ b/plugins/impex/png/kis_wdg_options_png.ui @@ -1,215 +1,215 @@ KisWdgOptionsPNG 0 0 546 243 PNG Options 0 0 0 0 0 6 <html><head/><body><p><span style=" font-weight:600;">PNG</span> files have <span style=" font-style:italic;">two</span> options to save <span style=" font-weight:600;">sRGB</span> information: as a tag or as an explicit profile. For use with in websites, <span style=" font-style:italic;">disable</span> this option. For interchange with other applications, <span style=" font-style:italic;">enable</span> this option.</p></body></html> Embed sRGB profile Force convert to sRGB Note: the compression level does not change the quality of the result <p>Adjust the compression time. Better compression takes longer. <br>Note: the compression level does not change the quality of the result.</p> Note: the compression level does not change the quality of the result <p>Adjust the compression time. Better compression takes longer. <br>Note: the compression level does not change the quality of the result.</p> Compression (Lossless): Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing <p>Adjust the compression time. Better compression takes longer. <br>Note: the compression level does not change the quality of the result.</p> Small File Size Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter <p>Adjust the compression time. Better compression takes longer. <br>Note: the compression level does not change the quality of the result.</p> Large file size - - - Disable to get smaller files if your image has no transparency - - - <p>The Portable Network Graphics (PNG) file format allows transparency in your image to be stored by saving an alpha channel. -You can uncheck the box if you are not using transparency and you want to make the resulting file smaller .<br>Always saving the alpha channel is recommended.</p> - - - Store alpha channel (transparency) - - - true - - - - Use interlacing when publishing on the Internet. <p>Interlacing is useful if you intend to publish your image on the Internet.<br> Enabling interlacing will cause the image to be displayed by the browser even while downloading.</p> Interlacing - + Indexed PNG images are smaller. If you enabled this option, your image will be analyzed to see whether it is possible to save as an indexed PNG. Save as indexed PNG, if possible true + + + + Disable to get smaller files if your image has no transparency + + + <p>The Portable Network Graphics (PNG) file format allows transparency in your image to be stored by saving an alpha channel. +You can uncheck the box if you are not using transparency and you want to make the resulting file smaller .<br>Always saving the alpha channel is recommended.</p> + + + Store alpha channel (transparency) + + + true + + + Transparent color: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 50 0 <html><head/><body><p>Background color to replace transparent pixels with.</p></body></html> Qt::Vertical QSizePolicy::Expanding 414 16 KisDoubleSliderSpinBox QWidget
kis_slider_spin_box.h
1
KisColorButton QPushButton
kis_color_button.h