diff --git a/plugins/extensions/separate_channels/dlg_separate.cc b/plugins/extensions/separate_channels/dlg_separate.cc index 582e0c28ac..04fc2a374d 100644 --- a/plugins/extensions/separate_channels/dlg_separate.cc +++ b/plugins/extensions/separate_channels/dlg_separate.cc @@ -1,124 +1,123 @@ /* * dlg_separate.cc - part of KimageShop^WKrayon^WKrita * * Copyright (c) 2004 Boudewijn Rempt * * 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 "dlg_separate.h" #include #include #include #include +#include + #include #include DlgSeparate::DlgSeparate(const QString & imageCS, const QString & layerCS, QWidget * parent, const char * name) : KoDialog(parent) , m_imageCS(imageCS) , m_layerCS(layerCS) { setObjectName(name); setCaption(i18n("Separate Image")); setButtons(Ok | Cancel); setDefaultButton(Ok); m_page = new WdgSeparations(this); Q_CHECK_PTR(m_page); setMainWidget(m_page); resize(m_page->sizeHint()); m_page->lblColormodel->setText(layerCS); - m_page->grpOutput->hide(); connect(m_page->radioCurrentLayer, SIGNAL(toggled(bool)), this, SLOT(slotSetColorSpaceLabel())); connect(m_page->radioAllLayers, SIGNAL(toggled(bool)), this, SLOT(slotSetColorSpaceLabel())); - connect(m_page->chkColors, SIGNAL(toggled(bool)), this, SLOT(disableDownScaleIfPossible(bool))); + connect(m_page->chkColors, SIGNAL(toggled(bool)), this, SLOT(separateToColorActivated(bool))); connect(this, SIGNAL(okClicked()), this, SLOT(okClicked())); + + KisDialogStateSaver::restoreState(m_page, "krita/separate channels"); } DlgSeparate::~DlgSeparate() { + KisDialogStateSaver::saveState(m_page, "krita/separate channels"); delete m_page; } enumSepAlphaOptions DlgSeparate::getAlphaOptions() { if (m_page->radioCopyAlpha->isChecked()) return COPY_ALPHA_TO_SEPARATIONS; if (m_page->radioDiscardAlpha->isChecked()) return DISCARD_ALPHA; if (m_page->radioSeparateAlpha->isChecked()) return CREATE_ALPHA_SEPARATION; return COPY_ALPHA_TO_SEPARATIONS; } enumSepSource DlgSeparate::getSource() { if (m_page->radioCurrentLayer->isChecked()) return CURRENT_LAYER; if (m_page->radioAllLayers->isChecked()) return ALL_LAYERS; - //if (XXX) return VISIBLE_LAYERS; - return CURRENT_LAYER; } -enumSepOutput DlgSeparate::getOutput() -{ - if (m_page->radioLayers->isChecked()) return TO_LAYERS; - if (m_page->radioImages->isChecked()) return TO_IMAGES; - - return TO_LAYERS; -} - - bool DlgSeparate::getDownscale() { return m_page->chkDownscale->isChecked(); } bool DlgSeparate::getToColor() { return m_page->chkColors->isChecked(); } +bool DlgSeparate::getActivateCurrentChannel() +{ + return m_page->chkActivateCurrentChannel->isChecked(); +} + void DlgSeparate::okClicked() { accept(); } -void DlgSeparate::disableDownScaleIfPossible(bool disable) +void DlgSeparate::separateToColorActivated(bool disable) { if (m_canDownScale) { m_page->chkDownscale->setDisabled(disable); } + m_page->chkActivateCurrentChannel->setDisabled(!disable); } void DlgSeparate::slotSetColorSpaceLabel() { if (m_page->radioCopyAlpha->isChecked()) { m_page->lblColormodel->setText(m_layerCS); } else if (m_page->radioAllLayers->isChecked()) { m_page->lblColormodel->setText(m_imageCS); } } void DlgSeparate::enableDownscale(bool enable) { m_canDownScale = enable; m_page->chkDownscale->setEnabled(enable); } diff --git a/plugins/extensions/separate_channels/dlg_separate.h b/plugins/extensions/separate_channels/dlg_separate.h index 29acc922ea..c86d00e667 100644 --- a/plugins/extensions/separate_channels/dlg_separate.h +++ b/plugins/extensions/separate_channels/dlg_separate.h @@ -1,77 +1,77 @@ /* * dlg_imagesize.h -- part of KimageShop^WKrayon^WKrita * * Copyright (c) 2005 Boudewijn Rempt * * 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. */ #ifndef DLG_SEPARATE #define DLG_SEPARATE #include #include #include "ui_wdg_separations.h" class WdgSeparations : public QWidget, public Ui::WdgSeparations { public: WdgSeparations(QWidget *parent) : QWidget(parent) { setupUi(this); } }; /** * This dialog allows the user to configure the decomposition of an image * into layers: one layer for each color channel. */ class DlgSeparate: public KoDialog { Q_OBJECT public: DlgSeparate(const QString & imageCS, const QString & layerCS, QWidget * parent = 0, const char* name = 0); ~DlgSeparate() override; public: enumSepAlphaOptions getAlphaOptions(); enumSepSource getSource(); - enumSepOutput getOutput(); bool getDownscale(); void enableDownscale(bool enable); bool getToColor(); + bool getActivateCurrentChannel(); private Q_SLOTS: void slotSetColorSpaceLabel(); void okClicked(); - void disableDownScaleIfPossible(bool disable); + void separateToColorActivated(bool disable); private: WdgSeparations * m_page; QString m_imageCS; QString m_layerCS; bool m_canDownScale {true}; }; #endif // DLG_SEPARATE diff --git a/plugins/extensions/separate_channels/kis_channel_separator.cc b/plugins/extensions/separate_channels/kis_channel_separator.cc index ffbc1fb45e..17fcbb22a3 100644 --- a/plugins/extensions/separate_channels/kis_channel_separator.cc +++ b/plugins/extensions/separate_channels/kis_channel_separator.cc @@ -1,272 +1,242 @@ /* * This file is part of Krita * * Copyright (c) 2005 Michael Thaler * * ported from Gimp, Copyright (C) 1997 Eiichi Takamori * original pixelize.c for GIMP 0.54 by Tracy Scott * * 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_channel_separator.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_iterator_ng.h" #include #include #include #include #include #include KisChannelSeparator::KisChannelSeparator(KisViewManager * view) - : m_viewManager(view) + : m_viewManager(view) { } -void KisChannelSeparator::separate(KoUpdater * progressUpdater, enumSepAlphaOptions alphaOps, enumSepSource sourceOps, enumSepOutput outputOps, bool downscale, bool toColor) +void KisChannelSeparator::separate(KoUpdater * progressUpdater, enumSepAlphaOptions alphaOps, enumSepSource sourceOps, bool downscale, bool toColor, bool activateCurrentChannel) { KisImageSP image = m_viewManager->image(); if (!image) return; KisPaintDeviceSP src; // Use the flattened image, if required switch (sourceOps) { case ALL_LAYERS: // the content will be locked later src = image->projection(); break; case CURRENT_LAYER: src = m_viewManager->activeDevice(); break; default: break; } if (!src) return; progressUpdater->setProgress(1); const KoColorSpace * dstCs = 0; quint32 numberOfChannels = src->channelCount(); const KoColorSpace * srcCs = src->colorSpace(); QList channels = srcCs->channels(); - vKisPaintDeviceSP layers; - - QList::const_iterator begin = channels.constBegin(); - QList::const_iterator end = channels.constEnd(); + vKisPaintDeviceSP paintDevices; QRect rect = src->exactBounds(); image->lock(); int i = 0; - for (QList::const_iterator it = begin; it != end; ++it) { - - KoChannelInfo * ch = (*it); + for (QList::const_iterator it = channels.constBegin(); it != channels.constEnd(); ++it) { + KoChannelInfo *ch = (*it); if (ch->channelType() == KoChannelInfo::ALPHA && alphaOps != CREATE_ALPHA_SEPARATION) { continue; } qint32 channelSize = ch->size(); qint32 channelPos = ch->pos(); qint32 destSize = 1; KisPaintDeviceSP dev; if (toColor) { // We don't downscale if we separate to color channels dev = new KisPaintDevice(srcCs); - } else { + } + else { if (channelSize == 1 || downscale) { dev = new KisPaintDevice(KoColorSpaceRegistry::instance()->colorSpace(GrayAColorModelID.id(), Integer8BitsColorDepthID.id(), 0)); } else { dev = new KisPaintDevice(KoColorSpaceRegistry::instance()->colorSpace(GrayAColorModelID.id(), Integer16BitsColorDepthID.id(), 0)); destSize = 2; } } dstCs = dev->colorSpace(); - layers.push_back(dev); + paintDevices.push_back(dev); KisHLineConstIteratorSP srcIt = src->createHLineConstIteratorNG(rect.x(), rect.y(), rect.width()); KisHLineIteratorSP dstIt = dev->createHLineIteratorNG(rect.x(), rect.y(), rect.width()); for (qint32 row = 0; row < rect.height(); ++row) { do { if (toColor) { dstCs->singleChannelPixel(dstIt->rawData(), srcIt->oldRawData(), channelPos); if (alphaOps == COPY_ALPHA_TO_SEPARATIONS) { //dstCs->setAlpha(dstIt->rawData(), srcIt->oldRawData()[srcAlphaPos], 1); dstCs->setOpacity(dstIt->rawData(), srcCs->opacityU8(srcIt->oldRawData()), 1); } else { dstCs->setOpacity(dstIt->rawData(), OPACITY_OPAQUE_U8, 1); } } else { // To grayscale // Decide whether we need downscaling if (channelSize == 1 && destSize == 1) { // Both 8-bit channels dstIt->rawData()[0] = srcIt->oldRawData()[channelPos]; if (alphaOps == COPY_ALPHA_TO_SEPARATIONS) { dstCs->setOpacity(dstIt->rawData(), srcCs->opacityU8(srcIt->oldRawData()), 1); } else { dstCs->setOpacity(dstIt->rawData(), OPACITY_OPAQUE_U8, 1); } } else if (channelSize == 2 && destSize == 2) { // Both 16-bit dstIt->rawData()[0] = srcIt->oldRawData()[channelPos]; dstIt->rawData()[1] = srcIt->oldRawData()[channelPos + 1]; if (alphaOps == COPY_ALPHA_TO_SEPARATIONS) { dstCs->setOpacity(dstIt->rawData(), srcCs->opacityU8(srcIt->oldRawData()), 1); } else { dstCs->setOpacity(dstIt->rawData(), OPACITY_OPAQUE_U8, 1); } } else if (channelSize != 1 && destSize == 1) { // Downscale memset(dstIt->rawData(), srcCs->scaleToU8(srcIt->oldRawData(), channelPos), 1); // XXX: Do alpha dstCs->setOpacity(dstIt->rawData(), OPACITY_OPAQUE_U8, 1); } else if (channelSize != 2 && destSize == 2) { // Upscale dstIt->rawData()[0] = srcCs->scaleToU8(srcIt->oldRawData(), channelPos); // XXX: Do alpha dstCs->setOpacity(dstIt->rawData(), OPACITY_OPAQUE_U8, 1); } } } while (dstIt->nextPixel() && srcIt->nextPixel()); dstIt->nextRow(); srcIt->nextRow(); } ++i; progressUpdater->setProgress((i * 100) / numberOfChannels); if (progressUpdater->interrupted()) { break; } } - vKisPaintDeviceSP_it deviceIt = layers.begin(); - - progressUpdater->setProgress(100); + vKisPaintDeviceSP::const_iterator paintDeviceIterator = paintDevices.cbegin(); if (!progressUpdater->interrupted()) { - - KisUndoAdapter * undo = image->undoAdapter(); - if (outputOps == TO_LAYERS) { - undo->beginMacro(kundo2_i18n("Separate Image")); - } + KisNodeCommandsAdapter adapter(m_viewManager); + adapter.beginMacro(kundo2_i18n("Separate Image")); // Flatten the image if required - switch (sourceOps) { - case(ALL_LAYERS): + if (sourceOps == ALL_LAYERS) { image->flatten(0); - break; - default: - break; } - KisNodeCommandsAdapter adapter(m_viewManager); - - for (QList::const_iterator it = begin; it != end; ++it) { - KoChannelInfo * ch = (*it); + for (QList::const_iterator it = channels.constBegin(); it != channels.constEnd(); ++it) { + KoChannelInfo *ch = (*it); if (ch->channelType() == KoChannelInfo::ALPHA && alphaOps != CREATE_ALPHA_SEPARATION) { // Don't make an separate separation of the alpha channel if the user didn't ask for it. continue; } - if (outputOps == TO_LAYERS) { - KisPaintLayerSP l = KisPaintLayerSP(new KisPaintLayer(image.data(), ch->name(), OPACITY_OPAQUE_U8, *deviceIt)); - adapter.addNode(l.data(), image->rootLayer(), 0); - } - else { - KoFileDialog dialog(m_viewManager->mainWindow(), KoFileDialog::SaveFile, "OpenDocument"); - dialog.setCaption(i18n("Export Layer") + '(' + ch->name() + ')'); - dialog.setDefaultDir(QStandardPaths::writableLocation(QStandardPaths::PicturesLocation)); - dialog.setMimeTypeFilters(KisImportExportManager::supportedMimeTypes(KisImportExportManager::Export)); - QUrl url = QUrl::fromUserInput(dialog.filename()); - - if (url.isEmpty()) - return; - - const QString mimeType = KisMimeDatabase::mimeTypeForFile(url.toLocalFile(), false); - - KisPaintLayerSP l = KisPaintLayerSP(new KisPaintLayer(image.data(), ch->name(), OPACITY_OPAQUE_U8, *deviceIt)); - QRect r = l->exactBounds(); - - KisDocument *d = KisPart::instance()->createDocument(); - - KisImageWSP dst = KisImageWSP(new KisImage(d->createUndoStore(), r.width(), r.height(), (*deviceIt)->colorSpace(), l->name())); - d->setCurrentImage(dst); - dst->addNode(l->clone().data(), dst->rootLayer()); - - d->exportDocumentSync(url, mimeType.toLatin1()); - - delete d; + KisPaintLayerSP l = new KisPaintLayer(image, ch->name(), OPACITY_OPAQUE_U8, *paintDeviceIterator); + if (toColor && activateCurrentChannel) { + QBitArray channelFlags(channels.count()); + int i = 0; + for (QList::const_iterator it2 = channels.constBegin(); it2 != channels.constEnd(); ++it2) { + channelFlags.setBit(i, (it == it2)); + i++; + } + l->setChannelFlags(channelFlags); } - ++deviceIt; + adapter.addNode(l.data(), image->rootLayer(), 0); + ++paintDeviceIterator; } - if (outputOps == TO_LAYERS) { - undo->endMacro(); - } - image->unlock(); + adapter.endMacro(); image->setModified(); } + image->unlock(); + + progressUpdater->setProgress(100); + + } diff --git a/plugins/extensions/separate_channels/kis_channel_separator.h b/plugins/extensions/separate_channels/kis_channel_separator.h index 12ff238835..7c5305e266 100644 --- a/plugins/extensions/separate_channels/kis_channel_separator.h +++ b/plugins/extensions/separate_channels/kis_channel_separator.h @@ -1,61 +1,56 @@ /* * This file is part of the KDE project * * Copyright (c) Michael Thaler * * 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. */ #ifndef _KIS_CHANNEL_SEPARATOR_H_ #define _KIS_CHANNEL_SEPARATOR_H_ class KoUpdater; class KisViewManager; enum enumSepAlphaOptions { COPY_ALPHA_TO_SEPARATIONS = 0, DISCARD_ALPHA = 1, CREATE_ALPHA_SEPARATION = 2 }; enum enumSepSource { CURRENT_LAYER = 0, ALL_LAYERS = 1, VISIBLE_LAYERS = 2 }; -enum enumSepOutput { - TO_LAYERS = 0, - TO_IMAGES = 1 -}; - class KisChannelSeparator { public: KisChannelSeparator(KisViewManager * view); virtual ~KisChannelSeparator() {} - void separate(KoUpdater * progress, enumSepAlphaOptions alphaOps, enumSepSource sourceOps, enumSepOutput outputOps, bool downscale, bool toColor); + void separate(KoUpdater * progress, enumSepAlphaOptions alphaOps, enumSepSource sourceOps, bool downscale, bool toColor, bool activateCurrentChannel); private: KisViewManager *m_viewManager; }; #endif diff --git a/plugins/extensions/separate_channels/kis_separate_channels_plugin.cc b/plugins/extensions/separate_channels/kis_separate_channels_plugin.cc index 545d1ffb71..a227fd8b75 100644 --- a/plugins/extensions/separate_channels/kis_separate_channels_plugin.cc +++ b/plugins/extensions/separate_channels/kis_separate_channels_plugin.cc @@ -1,99 +1,99 @@ /* * This file is part of the KDE project * * Copyright (c) 2005 Michael Thaler * * 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_separate_channels_plugin.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kis_channel_separator.h" #include "dlg_separate.h" K_PLUGIN_FACTORY_WITH_JSON(KisSeparateChannelsPluginFactory, "kritaseparatechannels.json", registerPlugin();) KisSeparateChannelsPlugin::KisSeparateChannelsPlugin(QObject *parent, const QVariantList &) : KisActionPlugin(parent) { KisAction *action = createAction("separate"); connect(action, SIGNAL(triggered(bool)), SLOT(slotSeparate())); } KisSeparateChannelsPlugin::~KisSeparateChannelsPlugin() { } void KisSeparateChannelsPlugin::slotSeparate() { KisImageSP image = viewManager()->image(); if (!image) return; KisLayerSP l = viewManager()->nodeManager()->activeLayer(); if (!l) return; KisPaintDeviceSP dev = l->paintDevice(); if (!dev) return; DlgSeparate * dlgSeparate = new DlgSeparate(dev->colorSpace()->name(), image->colorSpace()->name(), viewManager()->mainWindow(), "Separate"); Q_CHECK_PTR(dlgSeparate); dlgSeparate->setCaption(i18n("Separate Image")); // If we're 8-bits, disable the downscale option if (dev->pixelSize() == dev->channelCount()) { dlgSeparate->enableDownscale(false); } if (dlgSeparate->exec() == QDialog::Accepted) { QApplication::setOverrideCursor(Qt::BusyCursor); KisChannelSeparator separator(viewManager()); separator.separate(viewManager()->createUnthreadedUpdater(i18n("Separate Image")), dlgSeparate->getAlphaOptions(), dlgSeparate->getSource(), - dlgSeparate->getOutput(), dlgSeparate->getDownscale(), - dlgSeparate->getToColor()); + dlgSeparate->getToColor(), + dlgSeparate->getActivateCurrentChannel()); QApplication::restoreOverrideCursor(); } delete dlgSeparate; } #include "kis_separate_channels_plugin.moc" diff --git a/plugins/extensions/separate_channels/wdg_separations.ui b/plugins/extensions/separate_channels/wdg_separations.ui index 47860f8e16..c85dad9d89 100644 --- a/plugins/extensions/separate_channels/wdg_separations.ui +++ b/plugins/extensions/separate_channels/wdg_separations.ui @@ -1,183 +1,166 @@ WdgSeparations 0 0 - 570 + 498 392 Current color model: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 false 0 0 Source Current layer true Flatten all layers before separation - - - - Output - - - - - - To layers - - - true - - - - - - - To images - - - - - - Alpha Options Copy alpha channel to each separated channel as an alpha channel Discard alpha channel true Create separate separation from alpha channel Downscale to 8-bit before separating Output to color, not grayscale + + + + Activate only the current channel for the new node, deactivate all other channels. + + + Activate the current channel + + + Qt::Vertical QSizePolicy::Expanding 20 16 radioCurrentLayer - radioLayers radioDiscardAlpha chkDownscale chkColors