diff options
Diffstat (limited to 'src/imageplugins/channelmixer')
-rw-r--r-- | src/imageplugins/channelmixer/Makefile.am | 34 | ||||
-rw-r--r-- | src/imageplugins/channelmixer/channelmixer.cpp | 784 | ||||
-rw-r--r-- | src/imageplugins/channelmixer/channelmixer.h | 133 | ||||
-rw-r--r-- | src/imageplugins/channelmixer/channelmixertool.cpp | 774 | ||||
-rw-r--r-- | src/imageplugins/channelmixer/channelmixertool.h | 138 | ||||
-rw-r--r-- | src/imageplugins/channelmixer/digikamimageplugin_channelmixer.desktop | 51 | ||||
-rw-r--r-- | src/imageplugins/channelmixer/digikamimageplugin_channelmixer_ui.rc | 20 | ||||
-rw-r--r-- | src/imageplugins/channelmixer/imageplugin_channelmixer.cpp | 71 | ||||
-rw-r--r-- | src/imageplugins/channelmixer/imageplugin_channelmixer.h | 56 |
9 files changed, 2061 insertions, 0 deletions
diff --git a/src/imageplugins/channelmixer/Makefile.am b/src/imageplugins/channelmixer/Makefile.am new file mode 100644 index 00000000..61eaab34 --- /dev/null +++ b/src/imageplugins/channelmixer/Makefile.am @@ -0,0 +1,34 @@ +METASOURCES = AUTO + +INCLUDES = -I$(top_srcdir)/src/utilities/imageeditor/editor \ + -I$(top_srcdir)/src/utilities/imageeditor/canvas \ + -I$(top_srcdir)/src/libs/histogram \ + -I$(top_srcdir)/src/libs/levels \ + -I$(top_srcdir)/src/libs/curves \ + -I$(top_srcdir)/src/libs/whitebalance \ + -I$(top_srcdir)/src/libs/widgets/common \ + -I$(top_srcdir)/src/libs/widgets/iccprofiles \ + -I$(top_srcdir)/src/libs/widgets/imageplugins \ + -I$(top_srcdir)/src/libs/dialogs \ + -I$(top_srcdir)/src/libs/dimg \ + -I$(top_srcdir)/src/libs/dmetadata \ + -I$(top_srcdir)/src/libs/dimg/filters \ + -I$(top_srcdir)/src/digikam \ + $(LIBKDCRAW_CFLAGS) \ + $(all_includes) + +digikamimageplugin_channelmixer_la_SOURCES = imageplugin_channelmixer.cpp \ + channelmixertool.cpp + +digikamimageplugin_channelmixer_la_LIBADD = $(LIB_TDEPARTS) \ + $(top_builddir)/src/digikam/libdigikam.la + +digikamimageplugin_channelmixer_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) -ltdecore -ltdeui $(LIB_TQT) -ltdefx -lkdcraw -ltdeio + +kde_services_DATA = digikamimageplugin_channelmixer.desktop + +kde_module_LTLIBRARIES = digikamimageplugin_channelmixer.la + +rcdir = $(kde_datadir)/digikam +rc_DATA = digikamimageplugin_channelmixer_ui.rc + diff --git a/src/imageplugins/channelmixer/channelmixer.cpp b/src/imageplugins/channelmixer/channelmixer.cpp new file mode 100644 index 00000000..849cc1e8 --- /dev/null +++ b/src/imageplugins/channelmixer/channelmixer.cpp @@ -0,0 +1,784 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2005-02-26 + * Description : image channels mixer. + * + * Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * + * Load and save mixer gains methods inspired from + * Gimp 2.2.3 and copyrighted 2002 by Martin Guldahl + * <mguldahl at xmission dot com>. + * + * 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, 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. + * + * ============================================================ */ + +// C++ includes. + +#include <cstdio> +#include <cmath> +#include <cstring> +#include <cstdlib> +#include <cerrno> + +// TQt includes. + +#include <tqcolor.h> +#include <tqgroupbox.h> +#include <tqhgroupbox.h> +#include <tqvgroupbox.h> +#include <tqhbuttongroup.h> +#include <tqlabel.h> +#include <tqpainter.h> +#include <tqcombobox.h> +#include <tqspinbox.h> +#include <tqvbox.h> +#include <tqwhatsthis.h> +#include <tqpushbutton.h> +#include <tqlayout.h> +#include <tqframe.h> +#include <tqtimer.h> +#include <tqcheckbox.h> +#include <tqfile.h> +#include <tqtooltip.h> + +// KDE includes. + +#include <tdeconfig.h> +#include <kcursor.h> +#include <tdelocale.h> +#include <knuminput.h> +#include <tdemessagebox.h> +#include <tdeselect.h> +#include <tdefiledialog.h> +#include <tdeglobalsettings.h> +#include <tdeaboutdata.h> +#include <khelpmenu.h> +#include <kiconloader.h> +#include <tdeapplication.h> +#include <tdepopupmenu.h> +#include <kstandarddirs.h> + +// Local includes. + +#include "version.h" +#include "dimg.h" +#include "ddebug.h" +#include "imageiface.h" +#include "imagewidget.h" +#include "imagehistogram.h" +#include "histogramwidget.h" +#include "colorgradientwidget.h" +#include "dimgimagefilters.h" +#include "channelmixer.h" +#include "channelmixer.moc" + +namespace DigikamChannelMixerImagesPlugin +{ + +ChannelMixerDialog::ChannelMixerDialog(TQWidget* parent) + : Digikam::ImageDlgBase(parent, i18n("Color Channel Mixer"), + "channelmixer", true, false) +{ + m_destinationPreviewData = 0L; + + // About data and help button. + + TDEAboutData* about = new TDEAboutData("digikam", + I18N_NOOP("Color Channel Mixer"), + digikam_version, + I18N_NOOP("An image color channel mixer plugin for digiKam."), + TDEAboutData::License_GPL, + "(c) 2005-2008, Gilles Caulier", + 0, + "http://www.digikam.org"); + + about->addAuthor("Gilles Caulier", I18N_NOOP("Author and maintainer"), + "caulier dot gilles at gmail dot com"); + + setAboutData(about); + + // ------------------------------------------------------------- + + m_previewWidget = new Digikam::ImageWidget("channelmixer Tool Dialog", plainPage(), + i18n("<p>You can see here the image's color channels' " + "gains adjustments preview. You can pick color on image " + "to see the color level corresponding on histogram.")); + setPreviewAreaWidget(m_previewWidget); + + // ------------------------------------------------------------- + + TQWidget *gboxSettings = new TQWidget(plainPage()); + TQGridLayout* grid = new TQGridLayout( gboxSettings, 9, 4, spacingHint()); + + TQLabel *label1 = new TQLabel(i18n("Channel:"), gboxSettings); + label1->setAlignment ( TQt::AlignRight | TQt::AlignVCenter ); + m_channelCB = new TQComboBox( false, gboxSettings ); + m_channelCB->insertItem( i18n("Red") ); + m_channelCB->insertItem( i18n("Green") ); + m_channelCB->insertItem( i18n("Blue") ); + m_channelCB->setCurrentText( i18n("Red") ); + TQWhatsThis::add( m_channelCB, i18n("<p>Select the color channel to mix here:<p>" + "<b>Red</b>: display the red image-channel values.<p>" + "<b>Green</b>: display the green image-channel values.<p>" + "<b>Blue</b>: display the blue image-channel values.<p>")); + + m_scaleBG = new TQHButtonGroup(gboxSettings); + m_scaleBG->setExclusive(true); + m_scaleBG->setFrameShape(TQFrame::NoFrame); + m_scaleBG->setInsideMargin( 0 ); + TQWhatsThis::add( m_scaleBG, i18n("<p>Select the histogram scale here.<p>" + "If the image's maximal counts are small, you can use the linear scale.<p>" + "Logarithmic scale can be used when the maximal counts are big; " + "if it is used, all values (small and large) will be visible on the graph.")); + + TQPushButton *linHistoButton = new TQPushButton( m_scaleBG ); + TQToolTip::add( linHistoButton, i18n( "<p>Linear" ) ); + m_scaleBG->insert(linHistoButton, Digikam::HistogramWidget::LinScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-lin", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + TQString directory = TDEGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png"); + linHistoButton->setPixmap( TQPixmap( directory + "histogram-lin.png" ) ); + linHistoButton->setToggleButton(true); + + TQPushButton *logHistoButton = new TQPushButton( m_scaleBG ); + TQToolTip::add( logHistoButton, i18n( "<p>Logarithmic" ) ); + m_scaleBG->insert(logHistoButton, Digikam::HistogramWidget::LogScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-log", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png"); + logHistoButton->setPixmap( TQPixmap( directory + "histogram-log.png" ) ); + logHistoButton->setToggleButton(true); + + TQHBoxLayout* l1 = new TQHBoxLayout(); + l1->addWidget(label1); + l1->addWidget(m_channelCB); + l1->addStretch(10); + l1->addWidget(m_scaleBG); + + grid->addMultiCellLayout(l1, 0, 0, 0, 4); + + // ------------------------------------------------------------- + + TQVBox *histoBox = new TQVBox(gboxSettings); + m_histogramWidget = new Digikam::HistogramWidget(256, 140, histoBox, false, true, true); + TQWhatsThis::add( m_histogramWidget, i18n("<p>Here you can see the target preview image histogram drawing " + "of the selected image channel. This one is re-computed at any " + "mixer settings changes.")); + TQLabel *space = new TQLabel(histoBox); + space->setFixedHeight(1); + m_hGradient = new Digikam::ColorGradientWidget( Digikam::ColorGradientWidget::Horizontal, 10, histoBox ); + m_hGradient->setColors( TQColor( "black" ), TQColor( "red" ) ); + + grid->addMultiCellWidget(histoBox, 1, 2, 0, 4); + + // ------------------------------------------------------------- + + TQLabel *redLabel = new TQLabel(i18n("Red:"), gboxSettings); + m_redGain = new KDoubleNumInput(gboxSettings); + m_redGain->setPrecision(0); + m_redGain->setRange(-200.0, 200.0, 1, true); + TQWhatsThis::add( m_redGain, i18n("<p>Select the red color gain in percent for the current channel here.")); + + TQLabel *blueLabel = new TQLabel(i18n("Blue:"), gboxSettings); + m_greenGain = new KDoubleNumInput(gboxSettings); + m_greenGain->setPrecision(0); + m_greenGain->setRange(-200.0, 200.0, 1, true); + TQWhatsThis::add( m_greenGain, i18n("<p>Select the green color gain in percent for the current channel here.")); + + TQLabel *greenLabel = new TQLabel(i18n("Green:"), gboxSettings); + m_blueGain = new KDoubleNumInput(gboxSettings); + m_blueGain->setPrecision(0); + m_blueGain->setRange(-200.0, 200.0, 1, true); + TQWhatsThis::add( m_blueGain, i18n("<p>Select the blue color gain in percent for the current channel here.")); + + m_resetButton = new TQPushButton(i18n("&Reset"), gboxSettings); + TQWhatsThis::add( m_resetButton, i18n("Reset color channels' gains settings from the currently selected channel.")); + + grid->addMultiCellWidget(redLabel, 3, 3, 0, 0); + grid->addMultiCellWidget(greenLabel, 4, 4, 0, 0); + grid->addMultiCellWidget(blueLabel, 5, 5, 0, 0); + grid->addMultiCellWidget(m_redGain, 3, 3, 1, 4); + grid->addMultiCellWidget(m_greenGain, 4, 4, 1, 4); + grid->addMultiCellWidget(m_blueGain, 5, 5, 1, 4); + grid->addMultiCellWidget(m_resetButton, 6, 6, 0, 1); + + // ------------------------------------------------------------- + + m_monochrome = new TQCheckBox( i18n("Monochrome"), gboxSettings); + TQWhatsThis::add( m_monochrome, i18n("<p>Enable this option if you want the image rendered in monochrome mode. " + "In this mode, the histogram will display only luminosity values.")); + + m_preserveLuminosity = new TQCheckBox( i18n("Preserve luminosity"), gboxSettings); + TQWhatsThis::add( m_preserveLuminosity, i18n("<p>Enable this option is you want preserve the image luminosity.")); + + grid->addMultiCellWidget(m_monochrome, 7, 7, 0, 4); + grid->addMultiCellWidget(m_preserveLuminosity, 8, 8, 0, 4); + grid->setRowStretch(9, 10); + + setUserAreaWidget(gboxSettings); + + // ------------------------------------------------------------- + // Channels and scale selection slots. + + connect(m_channelCB, TQ_SIGNAL(activated(int)), + this, TQ_SLOT(slotChannelChanged(int))); + + connect(m_scaleBG, TQ_SIGNAL(released(int)), + this, TQ_SLOT(slotScaleChanged(int))); + + connect(m_previewWidget, TQ_SIGNAL(spotPositionChangedFromTarget( const Digikam::DColor &, const TQPoint & )), + this, TQ_SLOT(slotColorSelectedFromTarget( const Digikam::DColor & ))); + + connect(m_previewWidget, TQ_SIGNAL(signalResized()), + this, TQ_SLOT(slotEffect())); + + // ------------------------------------------------------------- + // Gains settings slots. + + connect(m_redGain, TQ_SIGNAL(valueChanged(double)), + this, TQ_SLOT(slotGainsChanged())); + + connect(m_greenGain, TQ_SIGNAL(valueChanged(double)), + this, TQ_SLOT(slotGainsChanged())); + + connect(m_blueGain, TQ_SIGNAL(valueChanged(double)), + this, TQ_SLOT(slotGainsChanged())); + + connect(m_preserveLuminosity, TQ_SIGNAL(toggled (bool)), + this, TQ_SLOT(slotEffect())); + + connect(m_monochrome, TQ_SIGNAL(toggled (bool)), + this, TQ_SLOT(slotMonochromeActived(bool))); + + // ------------------------------------------------------------- + // Bouttons slots. + + connect(m_resetButton, TQ_SIGNAL(clicked()), + this, TQ_SLOT(slotResetCurrentChannel())); +} + +ChannelMixerDialog::~ChannelMixerDialog() +{ + m_histogramWidget->stopHistogramComputation(); + + if (m_destinationPreviewData) + delete [] m_destinationPreviewData; + + delete m_histogramWidget; +} + +void ChannelMixerDialog::slotResetCurrentChannel() +{ + switch( m_channelCB->currentItem() ) + { + case GreenChannelGains: // Green. + m_greenRedGain = 0.0; + m_greenGreenGain = 1.0; + m_greenBlueGain = 0.0; + break; + + case BlueChannelGains: // Blue. + m_blueRedGain = 0.0; + m_blueGreenGain = 0.0; + m_blueBlueGain = 1.0; + break; + + default: // Red or monochrome. + if ( m_monochrome->isChecked() ) + { + m_blackRedGain = 1.0; + m_blackGreenGain = 0.0; + m_blackBlueGain = 0.0; + } + else + { + m_redRedGain = 1.0; + m_redGreenGain = 0.0; + m_redBlueGain = 0.0; + } + break; + } + + adjustSliders(); + slotEffect(); + m_histogramWidget->reset(); +} + +void ChannelMixerDialog::slotColorSelectedFromTarget( const Digikam::DColor &color ) +{ + m_histogramWidget->setHistogramGuideByColor(color); +} + +void ChannelMixerDialog::slotGainsChanged() +{ + switch( m_channelCB->currentItem() ) + { + case GreenChannelGains: // Green. + m_greenRedGain = m_redGain->value() / 100.0; + m_greenGreenGain = m_greenGain->value() / 100.0; + m_greenBlueGain = m_blueGain->value() / 100.0; + break; + + case BlueChannelGains: // Blue. + m_blueRedGain = m_redGain->value() / 100.0; + m_blueGreenGain = m_greenGain->value() / 100.0; + m_blueBlueGain = m_blueGain->value() / 100.0; + break; + + default: // Red or monochrome. + if ( m_monochrome->isChecked() ) + { + m_blackRedGain = m_redGain->value() / 100.0; + m_blackGreenGain = m_greenGain->value() / 100.0; + m_blackBlueGain = m_blueGain->value() / 100.0; + } + else + { + m_redRedGain = m_redGain->value() / 100.0; + m_redGreenGain = m_greenGain->value() / 100.0; + m_redBlueGain = m_blueGain->value() / 100.0; + } + break; + } + + slotTimer(); +} + +void ChannelMixerDialog::adjustSliders(void) +{ + m_redGain->blockSignals(true); + m_greenGain->blockSignals(true); + m_blueGain->blockSignals(true); + + switch( m_channelCB->currentItem() ) + { + case GreenChannelGains: // Green. + m_redGain->setValue(m_greenRedGain * 100.0); + m_greenGain->setValue(m_greenGreenGain * 100.0); + m_blueGain->setValue(m_greenBlueGain * 100.0); + break; + + case BlueChannelGains: // Blue. + m_redGain->setValue(m_blueRedGain * 100.0); + m_greenGain->setValue(m_blueGreenGain * 100.0); + m_blueGain->setValue(m_blueBlueGain * 100.0); + break; + + default: // Red or monochrome. + if ( m_monochrome->isChecked() ) + { + m_redGain->setValue(m_blackRedGain * 100.0); + m_greenGain->setValue(m_blackGreenGain * 100.0); + m_blueGain->setValue(m_blackBlueGain * 100.0); + } + else + { + m_redGain->setValue(m_redRedGain * 100.0); + m_greenGain->setValue(m_redGreenGain * 100.0); + m_blueGain->setValue(m_redBlueGain * 100.0); + } + break; + } + + m_redGain->blockSignals(false); + m_greenGain->blockSignals(false); + m_blueGain->blockSignals(false); +} + +void ChannelMixerDialog::slotMonochromeActived(bool mono) +{ + m_channelCB->setEnabled(!mono); + m_channelCB->setCurrentItem(RedChannelGains); // Red for monochrome. + slotChannelChanged(RedChannelGains); // Monochrome => display luminosity histogram value. +} + +void ChannelMixerDialog::slotEffect() +{ + Digikam::ImageIface* iface = m_previewWidget->imageIface(); + uchar *data = iface->getPreviewImage(); + int w = iface->previewWidth(); + int h = iface->previewHeight(); + bool sb = iface->previewSixteenBit(); + + // Create the new empty destination image data space. + m_histogramWidget->stopHistogramComputation(); + + if (m_destinationPreviewData) + delete [] m_destinationPreviewData; + + m_destinationPreviewData = new uchar[w*h*(sb ? 8 : 4)]; + Digikam::DImgImageFilters filter; + + if (m_monochrome->isChecked()) + { + filter.channelMixerImage(data, w, h, sb, // Image data. + m_preserveLuminosity->isChecked(), // Preserve luminosity. + m_monochrome->isChecked(), // Monochrome. + m_blackRedGain, m_blackGreenGain, m_blackBlueGain, // Red channel gains. + 0.0, 1.0, 0.0, // Green channel gains (not used). + 0.0, 0.0, 1.0); // Blue channel gains (not used). + } + else + { + filter.channelMixerImage(data, w, h, sb, // Image data. + m_preserveLuminosity->isChecked(), // Preserve luminosity. + m_monochrome->isChecked(), // Monochrome. + m_redRedGain, m_redGreenGain, m_redBlueGain, // Red channel gains. + m_greenRedGain, m_greenGreenGain, m_greenBlueGain, // Green channel gains. + m_blueRedGain, m_blueGreenGain, m_blueBlueGain); // Blue channel gains. + } + + iface->putPreviewImage(data); + m_previewWidget->updatePreview(); + + // Update histogram. + memcpy (m_destinationPreviewData, data, w*h*(sb ? 8 : 4)); + m_histogramWidget->updateData(m_destinationPreviewData, w, h, sb, 0, 0, 0, false); + delete [] data; +} + +void ChannelMixerDialog::finalRendering() +{ + kapp->setOverrideCursor( KCursor::waitCursor() ); + Digikam::ImageIface* iface = m_previewWidget->imageIface(); + uchar *data = iface->getOriginalImage(); + int w = iface->originalWidth(); + int h = iface->originalHeight(); + bool sb = iface->originalSixteenBit(); + + Digikam::DImgImageFilters filter; + + if (m_monochrome->isChecked()) + { + filter.channelMixerImage(data, w, h, sb, // Image data. + m_preserveLuminosity->isChecked(), // Preserve luminosity. + m_monochrome->isChecked(), // Monochrome. + m_blackRedGain, m_blackGreenGain, m_blackBlueGain, // Red channel gains. + 0.0, 1.0, 0.0, // Green channel gains (not used). + 0.0, 0.0, 1.0); // Blue channel gains (not used). + } + else + { + filter.channelMixerImage(data, w, h, sb, // Image data. + m_preserveLuminosity->isChecked(), // Preserve luminosity. + m_monochrome->isChecked(), // Monochrome. + m_redRedGain, m_redGreenGain, m_redBlueGain, // Red channel gains. + m_greenRedGain, m_greenGreenGain, m_greenBlueGain, // Green channel gains. + m_blueRedGain, m_blueGreenGain, m_blueBlueGain); // Blue channel gains. + } + + iface->putOriginalImage(i18n("Channel Mixer"), data); + delete [] data; + kapp->restoreOverrideCursor(); + accept(); +} + +void ChannelMixerDialog::slotChannelChanged(int channel) +{ + switch(channel) + { + case GreenChannelGains: // Green. + m_histogramWidget->m_channelType = Digikam::HistogramWidget::GreenChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "green" ) ); + break; + + case BlueChannelGains: // Blue. + m_histogramWidget->m_channelType = Digikam::HistogramWidget::BlueChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "blue" ) ); + break; + + default: // Red or monochrome. + if ( m_monochrome->isChecked() ) + { + m_histogramWidget->m_channelType = Digikam::HistogramWidget::ValueHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "white" ) ); + } + else + { + m_histogramWidget->m_channelType = Digikam::HistogramWidget::RedChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "red" ) ); + } + break; + } + + m_histogramWidget->repaint(false); + adjustSliders(); + slotEffect(); +} + +void ChannelMixerDialog::slotScaleChanged(int scale) +{ + m_histogramWidget->m_scaleType = scale; + m_histogramWidget->repaint(false); +} + +void ChannelMixerDialog::readUserSettings() +{ + TDEConfig* config = kapp->config(); + config->setGroup("channelmixer Tool Dialog"); + + m_channelCB->setCurrentItem(config->readNumEntry("Histogram Channel", 0)); // Luminosity. + m_scaleBG->setButton(config->readNumEntry("Histogram Scale", Digikam::HistogramWidget::LogScaleHistogram)); + + m_monochrome->setChecked(config->readBoolEntry("Monochrome", false)); + m_preserveLuminosity->setChecked(config->readNumEntry("PreserveLuminosity", false)); + + m_redRedGain = config->readDoubleNumEntry("RedRedGain", 1.0); + m_redGreenGain = config->readDoubleNumEntry("RedGreenGain", 0.0); + m_redBlueGain = config->readDoubleNumEntry("RedBlueGain", 0.0); + + m_greenRedGain = config->readDoubleNumEntry("GreenRedGain", 0.0); + m_greenGreenGain = config->readDoubleNumEntry("GreenGreenGain", 1.0); + m_greenBlueGain = config->readDoubleNumEntry("GreenBlueGain", 0.0); + + m_blueRedGain = config->readDoubleNumEntry("BlueRedGain", 0.0); + m_blueGreenGain = config->readDoubleNumEntry("BlueGreenGain", 0.0); + m_blueBlueGain = config->readDoubleNumEntry("BlueBlueGain", 1.0); + + m_blackRedGain = config->readDoubleNumEntry("BlackRedGain", 1.0); + m_blackGreenGain = config->readDoubleNumEntry("BlackGreenGain", 0.0); + m_blackBlueGain = config->readDoubleNumEntry("BlackBlueGain", 0.0); + + adjustSliders(); + m_histogramWidget->reset(); + + slotChannelChanged(m_channelCB->currentItem()); + slotScaleChanged(m_scaleBG->selectedId()); +} + +void ChannelMixerDialog::writeUserSettings() +{ + TDEConfig* config = kapp->config(); + config->setGroup("channelmixer Tool Dialog"); + config->writeEntry("Histogram Channel", m_channelCB->currentItem()); + config->writeEntry("Histogram Scale", m_scaleBG->selectedId()); + + config->writeEntry("Monochrome", m_monochrome->isChecked()); + config->writeEntry("PreserveLuminosity", m_preserveLuminosity->isChecked()); + + config->writeEntry("RedRedGain", m_redRedGain); + config->writeEntry("RedGreenGain", m_redGreenGain); + config->writeEntry("RedBlueGain", m_redBlueGain); + + config->writeEntry("GreenRedGain", m_greenRedGain); + config->writeEntry("GreenGreenGain", m_greenGreenGain); + config->writeEntry("GreenBlueGain", m_greenBlueGain); + + config->writeEntry("BlueRedGain", m_blueRedGain); + config->writeEntry("BlueGreenGain", m_blueGreenGain); + config->writeEntry("BlueBlueGain", m_blueBlueGain); + + config->writeEntry("BlackRedGain", m_blackRedGain); + config->writeEntry("BlackGreenGain", m_blackGreenGain); + config->writeEntry("BlackBlueGain", m_blackBlueGain); + + config->sync(); +} + +void ChannelMixerDialog::resetValues() +{ + m_monochrome->blockSignals(true); + m_preserveLuminosity->blockSignals(true); + + m_redRedGain = 1.0; + m_redGreenGain = 0.0; + m_redBlueGain = 0.0; + + m_greenRedGain = 0.0; + m_greenGreenGain = 1.0; + m_greenBlueGain = 0.0; + + m_blueRedGain = 0.0; + m_blueGreenGain = 0.0; + m_blueBlueGain = 1.0; + + m_blackRedGain = 1.0; + m_blackGreenGain = 0.0; + m_blackBlueGain = 0.0; + + adjustSliders(); + + m_monochrome->blockSignals(false); + m_preserveLuminosity->blockSignals(false); + m_channelCB->setEnabled(true); + + m_histogramWidget->reset(); + + slotChannelChanged(RedChannelGains); +} + +// Load all gains. +void ChannelMixerDialog::slotUser3() +{ + KURL loadGainsFileUrl; + FILE *fp = 0L; + int currentOutputChannel; + bool monochrome; + + loadGainsFileUrl = KFileDialog::getOpenURL(TDEGlobalSettings::documentPath(), + TQString( "*" ), this, + TQString( i18n("Select Gimp Gains Mixer File to Load")) ); + if( loadGainsFileUrl.isEmpty() ) + return; + + fp = fopen(TQFile::encodeName(loadGainsFileUrl.path()), "r"); + + if ( fp ) + { + char buf1[1024]; + char buf2[1024]; + char buf3[1024]; + + buf1[0] = '\0'; + + fgets(buf1, 1023, fp); + + fscanf (fp, "%*s %s", buf1); + + // Get the current output channel in dialog. + + if (strcmp (buf1, "RED") == 0) + currentOutputChannel = RedChannelGains; + else if (strcmp (buf1, "GREEN") == 0) + currentOutputChannel = GreenChannelGains; + else if (strcmp (buf1, "BLUE") == 0) + currentOutputChannel = BlueChannelGains; + + fscanf (fp, "%*s %s", buf1); // preview flag, preserved for compatibility + + fscanf (fp, "%*s %s", buf1); + + if (strcmp (buf1, "true") == 0) + monochrome = true; + else + monochrome = false; + + fscanf (fp, "%*s %s", buf1); + + if (strcmp (buf1, "true") == 0) + m_preserveLuminosity->setChecked(true); + else + m_preserveLuminosity->setChecked(false); + + fscanf (fp, "%*s %s %s %s", buf1, buf2, buf3); + m_redRedGain = atof(buf1); + m_redGreenGain = atof(buf2); + m_redBlueGain = atof(buf3); + + fscanf (fp, "%*s %s %s %s", buf1, buf2, buf3); + m_greenRedGain = atof(buf1); + m_greenGreenGain = atof(buf2); + m_greenBlueGain = atof(buf3); + + fscanf (fp, "%*s %s %s %s", buf1, buf2, buf3); + m_blueRedGain = atof(buf1); + m_blueGreenGain = atof(buf2); + m_blueBlueGain = atof(buf3); + + fscanf (fp, "%*s %s %s %s", buf1, buf2, buf3); + m_blackRedGain = atof(buf1); + m_blackGreenGain = atof(buf2); + m_blackBlueGain = atof(buf3); + + fclose(fp); + + // Refresh settings. + m_monochrome->setChecked(monochrome); + m_channelCB->setCurrentItem(currentOutputChannel); + slotChannelChanged(currentOutputChannel); + } + else + { + KMessageBox::error(this, i18n("Cannot load settings from the Gains Mixer text file.")); + return; + } +} + +// Save all gains. +void ChannelMixerDialog::slotUser2() +{ + KURL saveGainsFileUrl; + FILE *fp = 0L; + + saveGainsFileUrl = KFileDialog::getSaveURL(TDEGlobalSettings::documentPath(), + TQString( "*" ), this, + TQString( i18n("Gimp Gains Mixer File to Save")) ); + if( saveGainsFileUrl.isEmpty() ) + return; + + fp = fopen(TQFile::encodeName(saveGainsFileUrl.path()), "w"); + + if ( fp ) + { + const char *str = 0L; + char buf1[256]; + char buf2[256]; + char buf3[256]; + + switch ( m_channelCB->currentItem() ) + { + case RedChannelGains: + str = "RED"; + break; + case GreenChannelGains: + str = "GREEN"; + break; + case BlueChannelGains: + str = "BLUE"; + break; + default: + DWarning() << "Unknown Color channel gains" << endl; + break; + } + + fprintf (fp, "# Channel Mixer Configuration File\n"); + + fprintf (fp, "CHANNEL: %s\n", str); + fprintf (fp, "PREVIEW: %s\n", "true"); // preserved for compatibility + fprintf (fp, "MONOCHROME: %s\n", + m_monochrome->isChecked() ? "true" : "false"); + fprintf (fp, "PRESERVE_LUMINOSITY: %s\n", + m_preserveLuminosity->isChecked() ? "true" : "false"); + + sprintf (buf1, "%5.3f", m_redRedGain); + sprintf (buf2, "%5.3f", m_redGreenGain); + sprintf (buf3, "%5.3f", m_redBlueGain); + fprintf (fp, "RED: %s %s %s\n", buf1, buf2,buf3); + + sprintf (buf1, "%5.3f", m_greenRedGain); + sprintf (buf2, "%5.3f", m_greenGreenGain); + sprintf (buf3, "%5.3f", m_greenBlueGain); + fprintf (fp, "GREEN: %s %s %s\n", buf1, buf2,buf3); + + sprintf (buf1, "%5.3f", m_blueRedGain); + sprintf (buf2, "%5.3f", m_blueGreenGain); + sprintf (buf3, "%5.3f", m_blueBlueGain); + fprintf (fp, "BLUE: %s %s %s\n", buf1, buf2,buf3); + + sprintf (buf1, "%5.3f", m_blackRedGain); + sprintf (buf2, "%5.3f", m_blackGreenGain); + sprintf (buf3, "%5.3f", m_blackBlueGain); + fprintf (fp, "BLACK: %s %s %s\n", buf1, buf2,buf3); + + fclose (fp); + } + else + { + KMessageBox::error(this, i18n("Cannot save settings to the Gains Mixer text file.")); + return; + } +} + +} // NameSpace DigikamChannelMixerImagesPlugin + diff --git a/src/imageplugins/channelmixer/channelmixer.h b/src/imageplugins/channelmixer/channelmixer.h new file mode 100644 index 00000000..9b4396d0 --- /dev/null +++ b/src/imageplugins/channelmixer/channelmixer.h @@ -0,0 +1,133 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2005-02-26 + * Description : image channels mixer. + * + * Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * + * 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, 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. + * + * ============================================================ */ + +#ifndef CHANNELMIXER_H +#define CHANNELMIXER_H + +// Digikam includes. + +#include "imagedlgbase.h" + +class TQCheckBox; +class TQComboBox; +class TQPushButton; +class TQHButtonGroup; + +class KDoubleNumInput; + +namespace Digikam +{ +class HistogramWidget; +class ColorGradientWidget; +class ImageWidget; +class DColor; +} + +namespace DigikamChannelMixerImagesPlugin +{ + +class ChannelMixerDialog : public Digikam::ImageDlgBase +{ + TQ_OBJECT + + +public: + + ChannelMixerDialog(TQWidget *parent); + ~ChannelMixerDialog(); + +private: + + void readUserSettings(); + void writeUserSettings(); + void resetValues(); + void finalRendering(); + void adjustSliders(); + +private slots: + + void slotUser2(); + void slotUser3(); + void slotResetCurrentChannel(); + void slotEffect(); + void slotChannelChanged(int channel); + void slotScaleChanged(int scale); + void slotGainsChanged(); + void slotMonochromeActived(bool mono); + void slotColorSelectedFromTarget(const Digikam::DColor &color); + +private: + + enum ColorChannelGains + { + RedChannelGains=0, + GreenChannelGains, + BlueChannelGains + }; + + enum HistogramScale + { + Linear=0, + Logarithmic + }; + +private: + + uchar *m_destinationPreviewData; + + double m_redRedGain; + double m_redGreenGain; + double m_redBlueGain; + double m_greenRedGain; + double m_greenGreenGain; + double m_greenBlueGain; + double m_blueRedGain; + double m_blueGreenGain; + double m_blueBlueGain; + double m_blackRedGain; + double m_blackGreenGain; + double m_blackBlueGain; + + TQComboBox *m_channelCB; + + TQHButtonGroup *m_scaleBG; + + KDoubleNumInput *m_redGain; + KDoubleNumInput *m_greenGain; + KDoubleNumInput *m_blueGain; + + TQPushButton *m_resetButton; + + TQCheckBox *m_preserveLuminosity; + TQCheckBox *m_monochrome; + + Digikam::ColorGradientWidget *m_hGradient; + + Digikam::HistogramWidget *m_histogramWidget; + + Digikam::ImageWidget *m_previewWidget; +}; + +} // NameSpace DigikamChannelMixerImagesPlugin + +#endif /* CHANNELMIXER_H */ diff --git a/src/imageplugins/channelmixer/channelmixertool.cpp b/src/imageplugins/channelmixer/channelmixertool.cpp new file mode 100644 index 00000000..c8215178 --- /dev/null +++ b/src/imageplugins/channelmixer/channelmixertool.cpp @@ -0,0 +1,774 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2005-02-26 + * Description : image channels mixer. + * + * Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * + * 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, 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. + * + * ============================================================ */ + +// C++ includes. + +#include <cstdio> +#include <cmath> +#include <cstring> +#include <cstdlib> +#include <cerrno> + +// TQt includes. + +#include <tqcheckbox.h> +#include <tqcolor.h> +#include <tqcombobox.h> +#include <tqfile.h> +#include <tqframe.h> +#include <tqgroupbox.h> +#include <tqhbuttongroup.h> +#include <tqhgroupbox.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqpainter.h> +#include <tqpushbutton.h> +#include <tqspinbox.h> +#include <tqtimer.h> +#include <tqtooltip.h> +#include <tqvbox.h> +#include <tqvgroupbox.h> +#include <tqwhatsthis.h> + +// KDE includes. + +#include <tdeconfig.h> +#include <tdeaboutdata.h> +#include <tdeapplication.h> +#include <kcursor.h> +#include <tdefiledialog.h> +#include <tdeglobalsettings.h> +#include <khelpmenu.h> +#include <kiconloader.h> +#include <tdelocale.h> +#include <tdemessagebox.h> +#include <tdepopupmenu.h> +#include <tdeselect.h> +#include <kstandarddirs.h> + +// LibKDcraw includes. + +#include <libkdcraw/rnuminput.h> + +// Local includes. + +#include "daboutdata.h" +#include "dimg.h" +#include "ddebug.h" +#include "imageiface.h" +#include "imagewidget.h" +#include "imagehistogram.h" +#include "histogramwidget.h" +#include "colorgradientwidget.h" +#include "dimgimagefilters.h" +#include "editortoolsettings.h" +#include "channelmixertool.h" +#include "channelmixertool.moc" + +using namespace KDcrawIface; +using namespace Digikam; + +namespace DigikamChannelMixerImagesPlugin +{ + +ChannelMixerTool::ChannelMixerTool(TQObject* parent) + : EditorTool(parent) +{ + m_destinationPreviewData = 0; + + setName("channelmixer"); + setToolName(i18n("Channel Mixer")); + setToolIcon(SmallIcon("channelmixer")); + + // ------------------------------------------------------------- + + m_previewWidget = new ImageWidget("channelmixer Tool", 0, + i18n("<p>You can see here the image's color channels' " + "gains adjustments preview. You can pick color on image " + "to see the color level corresponding on histogram.")); + setToolView(m_previewWidget); + + // ------------------------------------------------------------- + + m_gboxSettings = new EditorToolSettings(EditorToolSettings::Default| + EditorToolSettings::Load| + EditorToolSettings::SaveAs| + EditorToolSettings::Ok| + EditorToolSettings::Cancel); + TQGridLayout* grid = new TQGridLayout(m_gboxSettings->plainPage(), 9, 4); + + TQLabel *label1 = new TQLabel(i18n("Channel:"), m_gboxSettings->plainPage()); + label1->setAlignment ( TQt::AlignRight | TQt::AlignVCenter ); + m_channelCB = new TQComboBox( false, m_gboxSettings->plainPage() ); + m_channelCB->insertItem( i18n("Red") ); + m_channelCB->insertItem( i18n("Green") ); + m_channelCB->insertItem( i18n("Blue") ); + m_channelCB->setCurrentText( i18n("Red") ); + TQWhatsThis::add( m_channelCB, i18n("<p>Select the color channel to mix here:<p>" + "<b>Red</b>: display the red image-channel values.<p>" + "<b>Green</b>: display the green image-channel values.<p>" + "<b>Blue</b>: display the blue image-channel values.<p>")); + + m_scaleBG = new TQHButtonGroup(m_gboxSettings->plainPage()); + m_scaleBG->setExclusive(true); + m_scaleBG->setFrameShape(TQFrame::NoFrame); + m_scaleBG->setInsideMargin( 0 ); + TQWhatsThis::add( m_scaleBG, i18n("<p>Select the histogram scale here.<p>" + "If the image's maximal counts are small, you can use the linear scale.<p>" + "Logarithmic scale can be used when the maximal counts are big; " + "if it is used, all values (small and large) will be visible on the graph.")); + + TQPushButton *linHistoButton = new TQPushButton( m_scaleBG ); + TQToolTip::add( linHistoButton, i18n( "<p>Linear" ) ); + m_scaleBG->insert(linHistoButton, HistogramWidget::LinScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-lin", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + TQString directory = TDEGlobal::dirs()->findResourceDir("histogram-lin", "histogram-lin.png"); + linHistoButton->setPixmap( TQPixmap( directory + "histogram-lin.png" ) ); + linHistoButton->setToggleButton(true); + + TQPushButton *logHistoButton = new TQPushButton( m_scaleBG ); + TQToolTip::add( logHistoButton, i18n( "<p>Logarithmic" ) ); + m_scaleBG->insert(logHistoButton, HistogramWidget::LogScaleHistogram); + TDEGlobal::dirs()->addResourceType("histogram-log", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); + directory = TDEGlobal::dirs()->findResourceDir("histogram-log", "histogram-log.png"); + logHistoButton->setPixmap( TQPixmap( directory + "histogram-log.png" ) ); + logHistoButton->setToggleButton(true); + + TQHBoxLayout* l1 = new TQHBoxLayout(); + l1->addWidget(label1); + l1->addWidget(m_channelCB); + l1->addStretch(10); + l1->addWidget(m_scaleBG); + + // ------------------------------------------------------------- + + TQVBox *histoBox = new TQVBox(m_gboxSettings->plainPage()); + m_histogramWidget = new HistogramWidget(256, 140, histoBox, false, true, true); + TQWhatsThis::add( m_histogramWidget, i18n("<p>Here you can see the target preview image histogram drawing " + "of the selected image channel. This one is re-computed at any " + "mixer settings changes.")); + TQLabel *space = new TQLabel(histoBox); + space->setFixedHeight(1); + m_hGradient = new ColorGradientWidget( ColorGradientWidget::Horizontal, 10, histoBox ); + m_hGradient->setColors( TQColor( "black" ), TQColor( "red" ) ); + + // ------------------------------------------------------------- + + TQLabel *redLabel = new TQLabel(i18n("Red:"), m_gboxSettings->plainPage()); + m_redGain = new RDoubleNumInput(m_gboxSettings->plainPage()); + m_redGain->setPrecision(0); + m_redGain->setRange(-200.0, 200.0, 1); + m_redGain->setDefaultValue(0); + TQWhatsThis::add( m_redGain, i18n("<p>Select the red color gain in percent for the current channel here.")); + + TQLabel *blueLabel = new TQLabel(i18n("Blue:"), m_gboxSettings->plainPage()); + m_greenGain = new RDoubleNumInput(m_gboxSettings->plainPage()); + m_greenGain->setPrecision(0); + m_greenGain->setRange(-200.0, 200.0, 1); + m_greenGain->setDefaultValue(0); + TQWhatsThis::add( m_greenGain, i18n("<p>Select the green color gain in percent for the current channel here.")); + + TQLabel *greenLabel = new TQLabel(i18n("Green:"), m_gboxSettings->plainPage()); + m_blueGain = new RDoubleNumInput(m_gboxSettings->plainPage()); + m_blueGain->setPrecision(0); + m_blueGain->setRange(-200.0, 200.0, 1); + m_blueGain->setDefaultValue(0); + TQWhatsThis::add( m_blueGain, i18n("<p>Select the blue color gain in percent for the current channel here.")); + + m_resetButton = new TQPushButton(i18n("&Reset"), m_gboxSettings->plainPage()); + TQWhatsThis::add( m_resetButton, i18n("Reset color channels' gains settings from the currently selected channel.")); + + // ------------------------------------------------------------- + + m_monochrome = new TQCheckBox( i18n("Monochrome"), m_gboxSettings->plainPage()); + TQWhatsThis::add( m_monochrome, i18n("<p>Enable this option if you want the image rendered in monochrome mode. " + "In this mode, the histogram will display only luminosity values.")); + + m_preserveLuminosity = new TQCheckBox( i18n("Preserve luminosity"), m_gboxSettings->plainPage()); + TQWhatsThis::add( m_preserveLuminosity, i18n("<p>Enable this option is you want preserve the image luminosity.")); + + grid->addMultiCellLayout(l1, 0, 0, 0, 4); + grid->addMultiCellWidget(histoBox, 1, 2, 0, 4); + grid->addMultiCellWidget(redLabel, 3, 3, 0, 0); + grid->addMultiCellWidget(greenLabel, 4, 4, 0, 0); + grid->addMultiCellWidget(blueLabel, 5, 5, 0, 0); + grid->addMultiCellWidget(m_redGain, 3, 3, 1, 4); + grid->addMultiCellWidget(m_greenGain, 4, 4, 1, 4); + grid->addMultiCellWidget(m_blueGain, 5, 5, 1, 4); + grid->addMultiCellWidget(m_resetButton, 6, 6, 0, 1); + grid->addMultiCellWidget(m_monochrome, 7, 7, 0, 4); + grid->addMultiCellWidget(m_preserveLuminosity, 8, 8, 0, 4); + grid->setRowStretch(9, 10); + grid->setMargin(m_gboxSettings->spacingHint()); + grid->setSpacing(m_gboxSettings->spacingHint()); + + setToolSettings(m_gboxSettings); + init(); + + // ------------------------------------------------------------- + // Channels and scale selection slots. + + connect(m_channelCB, TQ_SIGNAL(activated(int)), + this, TQ_SLOT(slotChannelChanged(int))); + + connect(m_scaleBG, TQ_SIGNAL(released(int)), + this, TQ_SLOT(slotScaleChanged(int))); + + connect(m_previewWidget, TQ_SIGNAL(spotPositionChangedFromTarget(const Digikam::DColor&, const TQPoint&)), + this, TQ_SLOT(slotColorSelectedFromTarget(const Digikam::DColor&))); + + connect(m_previewWidget, TQ_SIGNAL(signalResized()), + this, TQ_SLOT(slotEffect())); + + // ------------------------------------------------------------- + // Gains settings slots. + + connect(m_redGain, TQ_SIGNAL(valueChanged(double)), + this, TQ_SLOT(slotGainsChanged())); + + connect(m_greenGain, TQ_SIGNAL(valueChanged(double)), + this, TQ_SLOT(slotGainsChanged())); + + connect(m_blueGain, TQ_SIGNAL(valueChanged(double)), + this, TQ_SLOT(slotGainsChanged())); + + connect(m_preserveLuminosity, TQ_SIGNAL(toggled (bool)), + this, TQ_SLOT(slotEffect())); + + connect(m_monochrome, TQ_SIGNAL(toggled (bool)), + this, TQ_SLOT(slotMonochromeActived(bool))); + + // ------------------------------------------------------------- + // Bouttons slots. + + connect(m_resetButton, TQ_SIGNAL(clicked()), + this, TQ_SLOT(slotResetCurrentChannel())); +} + +ChannelMixerTool::~ChannelMixerTool() +{ + if (m_destinationPreviewData) + delete [] m_destinationPreviewData; +} + +void ChannelMixerTool::slotResetCurrentChannel() +{ + switch( m_channelCB->currentItem() ) + { + case GreenChannelGains: // Green. + m_greenRedGain = 0.0; + m_greenGreenGain = 1.0; + m_greenBlueGain = 0.0; + break; + + case BlueChannelGains: // Blue. + m_blueRedGain = 0.0; + m_blueGreenGain = 0.0; + m_blueBlueGain = 1.0; + break; + + default: // Red or monochrome. + if ( m_monochrome->isChecked() ) + { + m_blackRedGain = 1.0; + m_blackGreenGain = 0.0; + m_blackBlueGain = 0.0; + } + else + { + m_redRedGain = 1.0; + m_redGreenGain = 0.0; + m_redBlueGain = 0.0; + } + break; + } + + adjustSliders(); + slotEffect(); + m_histogramWidget->reset(); +} + +void ChannelMixerTool::slotColorSelectedFromTarget(const DColor& color) +{ + m_histogramWidget->setHistogramGuideByColor(color); +} + +void ChannelMixerTool::slotGainsChanged() +{ + switch( m_channelCB->currentItem() ) + { + case GreenChannelGains: // Green. + m_greenRedGain = m_redGain->value() / 100.0; + m_greenGreenGain = m_greenGain->value() / 100.0; + m_greenBlueGain = m_blueGain->value() / 100.0; + break; + + case BlueChannelGains: // Blue. + m_blueRedGain = m_redGain->value() / 100.0; + m_blueGreenGain = m_greenGain->value() / 100.0; + m_blueBlueGain = m_blueGain->value() / 100.0; + break; + + default: // Red or monochrome. + if ( m_monochrome->isChecked() ) + { + m_blackRedGain = m_redGain->value() / 100.0; + m_blackGreenGain = m_greenGain->value() / 100.0; + m_blackBlueGain = m_blueGain->value() / 100.0; + } + else + { + m_redRedGain = m_redGain->value() / 100.0; + m_redGreenGain = m_greenGain->value() / 100.0; + m_redBlueGain = m_blueGain->value() / 100.0; + } + break; + } + + slotTimer(); +} + +void ChannelMixerTool::adjustSliders() +{ + m_redGain->blockSignals(true); + m_greenGain->blockSignals(true); + m_blueGain->blockSignals(true); + + switch( m_channelCB->currentItem() ) + { + case GreenChannelGains: // Green. + m_redGain->setValue(m_greenRedGain * 100.0); + m_greenGain->setValue(m_greenGreenGain * 100.0); + m_blueGain->setValue(m_greenBlueGain * 100.0); + break; + + case BlueChannelGains: // Blue. + m_redGain->setValue(m_blueRedGain * 100.0); + m_greenGain->setValue(m_blueGreenGain * 100.0); + m_blueGain->setValue(m_blueBlueGain * 100.0); + break; + + default: // Red or monochrome. + if ( m_monochrome->isChecked() ) + { + m_redGain->setValue(m_blackRedGain * 100.0); + m_greenGain->setValue(m_blackGreenGain * 100.0); + m_blueGain->setValue(m_blackBlueGain * 100.0); + } + else + { + m_redGain->setValue(m_redRedGain * 100.0); + m_greenGain->setValue(m_redGreenGain * 100.0); + m_blueGain->setValue(m_redBlueGain * 100.0); + } + break; + } + + m_redGain->blockSignals(false); + m_greenGain->blockSignals(false); + m_blueGain->blockSignals(false); +} + +void ChannelMixerTool::slotMonochromeActived(bool mono) +{ + m_channelCB->setEnabled(!mono); + m_channelCB->setCurrentItem(RedChannelGains); // Red for monochrome. + slotChannelChanged(RedChannelGains); // Monochrome => display luminosity histogram value. +} + +void ChannelMixerTool::slotEffect() +{ + ImageIface* iface = m_previewWidget->imageIface(); + uchar *data = iface->getPreviewImage(); + int w = iface->previewWidth(); + int h = iface->previewHeight(); + bool sb = iface->previewSixteenBit(); + + // Create the new empty destination image data space. + m_histogramWidget->stopHistogramComputation(); + + if (m_destinationPreviewData) + delete [] m_destinationPreviewData; + + m_destinationPreviewData = new uchar[w*h*(sb ? 8 : 4)]; + DImgImageFilters filter; + + if (m_monochrome->isChecked()) + { + filter.channelMixerImage(data, w, h, sb, // Image data. + m_preserveLuminosity->isChecked(), // Preserve luminosity. + m_monochrome->isChecked(), // Monochrome. + m_blackRedGain, m_blackGreenGain, m_blackBlueGain, // Red channel gains. + 0.0, 1.0, 0.0, // Green channel gains (not used). + 0.0, 0.0, 1.0); // Blue channel gains (not used). + } + else + { + filter.channelMixerImage(data, w, h, sb, // Image data. + m_preserveLuminosity->isChecked(), // Preserve luminosity. + m_monochrome->isChecked(), // Monochrome. + m_redRedGain, m_redGreenGain, m_redBlueGain, // Red channel gains. + m_greenRedGain, m_greenGreenGain, m_greenBlueGain, // Green channel gains. + m_blueRedGain, m_blueGreenGain, m_blueBlueGain); // Blue channel gains. + } + + iface->putPreviewImage(data); + m_previewWidget->updatePreview(); + + // Update histogram. + memcpy (m_destinationPreviewData, data, w*h*(sb ? 8 : 4)); + m_histogramWidget->updateData(m_destinationPreviewData, w, h, sb, 0, 0, 0, false); + delete [] data; +} + +void ChannelMixerTool::finalRendering() +{ + kapp->setOverrideCursor( KCursor::waitCursor() ); + ImageIface* iface = m_previewWidget->imageIface(); + uchar *data = iface->getOriginalImage(); + int w = iface->originalWidth(); + int h = iface->originalHeight(); + bool sb = iface->originalSixteenBit(); + + DImgImageFilters filter; + + if (m_monochrome->isChecked()) + { + filter.channelMixerImage(data, w, h, sb, // Image data. + m_preserveLuminosity->isChecked(), // Preserve luminosity. + m_monochrome->isChecked(), // Monochrome. + m_blackRedGain, m_blackGreenGain, m_blackBlueGain, // Red channel gains. + 0.0, 1.0, 0.0, // Green channel gains (not used). + 0.0, 0.0, 1.0); // Blue channel gains (not used). + } + else + { + filter.channelMixerImage(data, w, h, sb, // Image data. + m_preserveLuminosity->isChecked(), // Preserve luminosity. + m_monochrome->isChecked(), // Monochrome. + m_redRedGain, m_redGreenGain, m_redBlueGain, // Red channel gains. + m_greenRedGain, m_greenGreenGain, m_greenBlueGain, // Green channel gains. + m_blueRedGain, m_blueGreenGain, m_blueBlueGain); // Blue channel gains. + } + + iface->putOriginalImage(i18n("Channel Mixer"), data); + delete [] data; + kapp->restoreOverrideCursor(); +} + +void ChannelMixerTool::slotChannelChanged(int channel) +{ + switch(channel) + { + case GreenChannelGains: // Green. + m_histogramWidget->m_channelType = HistogramWidget::GreenChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "green" ) ); + break; + + case BlueChannelGains: // Blue. + m_histogramWidget->m_channelType = HistogramWidget::BlueChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "blue" ) ); + break; + + default: // Red or monochrome. + if ( m_monochrome->isChecked() ) + { + m_histogramWidget->m_channelType = HistogramWidget::ValueHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "white" ) ); + } + else + { + m_histogramWidget->m_channelType = HistogramWidget::RedChannelHistogram; + m_hGradient->setColors( TQColor( "black" ), TQColor( "red" ) ); + } + break; + } + + m_histogramWidget->repaint(false); + adjustSliders(); + slotEffect(); +} + +void ChannelMixerTool::slotScaleChanged(int scale) +{ + m_histogramWidget->m_scaleType = scale; + m_histogramWidget->repaint(false); +} + +void ChannelMixerTool::readSettings() +{ + TDEConfig* config = kapp->config(); + config->setGroup("channelmixer Tool"); + + m_channelCB->setCurrentItem(config->readNumEntry("Histogram Channel", 0)); // Luminosity. + m_scaleBG->setButton(config->readNumEntry("Histogram Scale", HistogramWidget::LogScaleHistogram)); + + m_monochrome->setChecked(config->readBoolEntry("Monochrome", false)); + m_preserveLuminosity->setChecked(config->readNumEntry("PreserveLuminosity", false)); + + m_redRedGain = config->readDoubleNumEntry("RedRedGain", 1.0); + m_redGreenGain = config->readDoubleNumEntry("RedGreenGain", 0.0); + m_redBlueGain = config->readDoubleNumEntry("RedBlueGain", 0.0); + + m_greenRedGain = config->readDoubleNumEntry("GreenRedGain", 0.0); + m_greenGreenGain = config->readDoubleNumEntry("GreenGreenGain", 1.0); + m_greenBlueGain = config->readDoubleNumEntry("GreenBlueGain", 0.0); + + m_blueRedGain = config->readDoubleNumEntry("BlueRedGain", 0.0); + m_blueGreenGain = config->readDoubleNumEntry("BlueGreenGain", 0.0); + m_blueBlueGain = config->readDoubleNumEntry("BlueBlueGain", 1.0); + + m_blackRedGain = config->readDoubleNumEntry("BlackRedGain", 1.0); + m_blackGreenGain = config->readDoubleNumEntry("BlackGreenGain", 0.0); + m_blackBlueGain = config->readDoubleNumEntry("BlackBlueGain", 0.0); + + adjustSliders(); + m_histogramWidget->reset(); + slotChannelChanged(m_channelCB->currentItem()); + slotScaleChanged(m_scaleBG->selectedId()); +} + +void ChannelMixerTool::writeSettings() +{ + TDEConfig* config = kapp->config(); + config->setGroup("channelmixer Tool"); + config->writeEntry("Histogram Channel", m_channelCB->currentItem()); + config->writeEntry("Histogram Scale", m_scaleBG->selectedId()); + + config->writeEntry("Monochrome", m_monochrome->isChecked()); + config->writeEntry("PreserveLuminosity", m_preserveLuminosity->isChecked()); + + config->writeEntry("RedRedGain", m_redRedGain); + config->writeEntry("RedGreenGain", m_redGreenGain); + config->writeEntry("RedBlueGain", m_redBlueGain); + + config->writeEntry("GreenRedGain", m_greenRedGain); + config->writeEntry("GreenGreenGain", m_greenGreenGain); + config->writeEntry("GreenBlueGain", m_greenBlueGain); + + config->writeEntry("BlueRedGain", m_blueRedGain); + config->writeEntry("BlueGreenGain", m_blueGreenGain); + config->writeEntry("BlueBlueGain", m_blueBlueGain); + + config->writeEntry("BlackRedGain", m_blackRedGain); + config->writeEntry("BlackGreenGain", m_blackGreenGain); + config->writeEntry("BlackBlueGain", m_blackBlueGain); + + m_previewWidget->writeSettings(); + + config->sync(); +} + +void ChannelMixerTool::slotResetSettings() +{ + m_monochrome->blockSignals(true); + m_preserveLuminosity->blockSignals(true); + + m_redRedGain = 1.0; + m_redGreenGain = 0.0; + m_redBlueGain = 0.0; + + m_greenRedGain = 0.0; + m_greenGreenGain = 1.0; + m_greenBlueGain = 0.0; + + m_blueRedGain = 0.0; + m_blueGreenGain = 0.0; + m_blueBlueGain = 1.0; + + m_blackRedGain = 1.0; + m_blackGreenGain = 0.0; + m_blackBlueGain = 0.0; + + adjustSliders(); + + m_monochrome->blockSignals(false); + m_preserveLuminosity->blockSignals(false); + m_channelCB->setEnabled(true); + + m_histogramWidget->reset(); + + slotChannelChanged(RedChannelGains); +} + +void ChannelMixerTool::slotLoadSettings() +{ + KURL loadGainsFileUrl; + FILE *fp = 0L; + int currentOutputChannel; + bool monochrome; + + loadGainsFileUrl = KFileDialog::getOpenURL(TDEGlobalSettings::documentPath(), + TQString( "*" ), kapp->activeWindow(), + TQString( i18n("Select Gimp Gains Mixer File to Load")) ); + if( loadGainsFileUrl.isEmpty() ) + return; + + fp = fopen(TQFile::encodeName(loadGainsFileUrl.path()), "r"); + + if ( fp ) + { + char buf1[1024]; + char buf2[1024]; + char buf3[1024]; + + buf1[0] = '\0'; + + fgets(buf1, 1023, fp); + + fscanf (fp, "%*s %s", buf1); + + // Get the current output channel in dialog. + + if (strcmp (buf1, "RED") == 0) + currentOutputChannel = RedChannelGains; + else if (strcmp (buf1, "GREEN") == 0) + currentOutputChannel = GreenChannelGains; + else if (strcmp (buf1, "BLUE") == 0) + currentOutputChannel = BlueChannelGains; + + fscanf (fp, "%*s %s", buf1); // preview flag, preserved for compatibility + + fscanf (fp, "%*s %s", buf1); + + if (strcmp (buf1, "true") == 0) + monochrome = true; + else + monochrome = false; + + fscanf (fp, "%*s %s", buf1); + + if (strcmp (buf1, "true") == 0) + m_preserveLuminosity->setChecked(true); + else + m_preserveLuminosity->setChecked(false); + + fscanf (fp, "%*s %s %s %s", buf1, buf2, buf3); + m_redRedGain = atof(buf1); + m_redGreenGain = atof(buf2); + m_redBlueGain = atof(buf3); + + fscanf (fp, "%*s %s %s %s", buf1, buf2, buf3); + m_greenRedGain = atof(buf1); + m_greenGreenGain = atof(buf2); + m_greenBlueGain = atof(buf3); + + fscanf (fp, "%*s %s %s %s", buf1, buf2, buf3); + m_blueRedGain = atof(buf1); + m_blueGreenGain = atof(buf2); + m_blueBlueGain = atof(buf3); + + fscanf (fp, "%*s %s %s %s", buf1, buf2, buf3); + m_blackRedGain = atof(buf1); + m_blackGreenGain = atof(buf2); + m_blackBlueGain = atof(buf3); + + fclose(fp); + + // Refresh settings. + m_monochrome->setChecked(monochrome); + m_channelCB->setCurrentItem(currentOutputChannel); + slotChannelChanged(currentOutputChannel); + } + else + { + KMessageBox::error(kapp->activeWindow(), i18n("Cannot load settings from the Gains Mixer text file.")); + return; + } +} + +void ChannelMixerTool::slotSaveAsSettings() +{ + KURL saveGainsFileUrl; + FILE *fp = 0L; + + saveGainsFileUrl = KFileDialog::getSaveURL(TDEGlobalSettings::documentPath(), + TQString( "*" ), kapp->activeWindow(), + TQString( i18n("Gimp Gains Mixer File to Save")) ); + if( saveGainsFileUrl.isEmpty() ) + return; + + fp = fopen(TQFile::encodeName(saveGainsFileUrl.path()), "w"); + + if ( fp ) + { + const char *str = 0L; + char buf1[256]; + char buf2[256]; + char buf3[256]; + + switch ( m_channelCB->currentItem() ) + { + case RedChannelGains: + str = "RED"; + break; + case GreenChannelGains: + str = "GREEN"; + break; + case BlueChannelGains: + str = "BLUE"; + break; + default: + DWarning() << "Unknown Color channel gains" << endl; + break; + } + + fprintf (fp, "# Channel Mixer Configuration File\n"); + + fprintf (fp, "CHANNEL: %s\n", str); + fprintf (fp, "PREVIEW: %s\n", "true"); // preserved for compatibility + fprintf (fp, "MONOCHROME: %s\n", + m_monochrome->isChecked() ? "true" : "false"); + fprintf (fp, "PRESERVE_LUMINOSITY: %s\n", + m_preserveLuminosity->isChecked() ? "true" : "false"); + + sprintf (buf1, "%5.3f", m_redRedGain); + sprintf (buf2, "%5.3f", m_redGreenGain); + sprintf (buf3, "%5.3f", m_redBlueGain); + fprintf (fp, "RED: %s %s %s\n", buf1, buf2,buf3); + + sprintf (buf1, "%5.3f", m_greenRedGain); + sprintf (buf2, "%5.3f", m_greenGreenGain); + sprintf (buf3, "%5.3f", m_greenBlueGain); + fprintf (fp, "GREEN: %s %s %s\n", buf1, buf2,buf3); + + sprintf (buf1, "%5.3f", m_blueRedGain); + sprintf (buf2, "%5.3f", m_blueGreenGain); + sprintf (buf3, "%5.3f", m_blueBlueGain); + fprintf (fp, "BLUE: %s %s %s\n", buf1, buf2,buf3); + + sprintf (buf1, "%5.3f", m_blackRedGain); + sprintf (buf2, "%5.3f", m_blackGreenGain); + sprintf (buf3, "%5.3f", m_blackBlueGain); + fprintf (fp, "BLACK: %s %s %s\n", buf1, buf2,buf3); + + fclose (fp); + } + else + { + KMessageBox::error(kapp->activeWindow(), i18n("Cannot save settings to the Gains Mixer text file.")); + return; + } +} + +} // NameSpace DigikamChannelMixerImagesPlugin diff --git a/src/imageplugins/channelmixer/channelmixertool.h b/src/imageplugins/channelmixer/channelmixertool.h new file mode 100644 index 00000000..c15a30cd --- /dev/null +++ b/src/imageplugins/channelmixer/channelmixertool.h @@ -0,0 +1,138 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2005-02-26 + * Description : image channels mixer. + * + * Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * + * 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, 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. + * + * ============================================================ */ + +#ifndef CHANNELMIXERTOOL_H +#define CHANNELMIXERTOOL_H + +// Digikam includes. + +#include "editortool.h" + +class TQCheckBox; +class TQComboBox; +class TQPushButton; +class TQHButtonGroup; + +namespace KDcrawIface +{ +class RDoubleNumInput; +} + +namespace Digikam +{ +class HistogramWidget; +class ColorGradientWidget; +class ImageWidget; +class DColor; +} + +namespace DigikamChannelMixerImagesPlugin +{ + +class ChannelMixerTool : public Digikam::EditorTool +{ + TQ_OBJECT + + +public: + + ChannelMixerTool(TQObject *parent); + ~ChannelMixerTool(); + +private: + + void readSettings(); + void writeSettings(); + void finalRendering(); + void adjustSliders(); + +private slots: + + void slotLoadSettings(); + void slotSaveAsSettings(); + void slotResetCurrentChannel(); + void slotEffect(); + void slotResetSettings(); + void slotChannelChanged(int channel); + void slotScaleChanged(int scale); + void slotGainsChanged(); + void slotMonochromeActived(bool mono); + void slotColorSelectedFromTarget(const Digikam::DColor &color); + +private: + + enum ColorChannelGains + { + RedChannelGains=0, + GreenChannelGains, + BlueChannelGains + }; + + enum HistogramScale + { + Linear=0, + Logarithmic + }; + +private: + + uchar *m_destinationPreviewData; + + double m_redRedGain; + double m_redGreenGain; + double m_redBlueGain; + double m_greenRedGain; + double m_greenGreenGain; + double m_greenBlueGain; + double m_blueRedGain; + double m_blueGreenGain; + double m_blueBlueGain; + double m_blackRedGain; + double m_blackGreenGain; + double m_blackBlueGain; + + TQComboBox *m_channelCB; + + TQHButtonGroup *m_scaleBG; + + KDcrawIface::RDoubleNumInput *m_redGain; + KDcrawIface::RDoubleNumInput *m_greenGain; + KDcrawIface::RDoubleNumInput *m_blueGain; + + TQPushButton *m_resetButton; + + TQCheckBox *m_preserveLuminosity; + TQCheckBox *m_monochrome; + + Digikam::ColorGradientWidget *m_hGradient; + + Digikam::HistogramWidget *m_histogramWidget; + + Digikam::ImageWidget *m_previewWidget; + + Digikam::EditorToolSettings *m_gboxSettings; +}; + +} // NameSpace DigikamChannelMixerImagesPlugin + +#endif /* CHANNELMIXERTOOL_H */ diff --git a/src/imageplugins/channelmixer/digikamimageplugin_channelmixer.desktop b/src/imageplugins/channelmixer/digikamimageplugin_channelmixer.desktop new file mode 100644 index 00000000..a855fffe --- /dev/null +++ b/src/imageplugins/channelmixer/digikamimageplugin_channelmixer.desktop @@ -0,0 +1,51 @@ +[Desktop Entry] +Name=ImagePlugin_ChannelMixer +Name[bg]=Приставка за снимки - Смесител на канали +Name[el]=ΠρόσθετοΕικόνας_ΑνάμειξηΚαναλιών +Name[fi]=KanavatasapainonSäätö +Name[hr]=Miješanje kanala +Name[it]=PluginImmagini_MixerDeiCanali +Name[nl]=Afbeeldingsplugin_Kanaalmixer +Name[sr]=Миксета канала +Name[sr@Latn]=Mikseta kanala +Name[sv]=Insticksprogram för kanalblandning +Name[tr]=ResimEklentisi_KanalKarıştırıcı +Name[xx]=xxImagePlugin_ChannelMixerxx +Type=Service +X-TDE-ServiceTypes=Digikam/ImagePlugin +Encoding=UTF-8 + +Comment=Image color channels mixer plugin for digiKam +Comment[bg]=Приставка на digiKam със смесител на цветови канали +Comment[ca]=Connector pel digiKam per mesclar els canals de color de la imatge +Comment[da]=Digikam plugin til at blande billedfarvekanaler +Comment[de]=digiKam-Modul zum Mischen von Farbkanälen eines Bildes +Comment[el]=Πρόσθετο μείκτη καναλιών χρώματος εικόνας για το digiKam +Comment[en_GB]=Image colour channels mixer plugin for digiKam +Comment[es]=Plugin para digiKam para la mezcla de los canales de color de imagen +Comment[et]=DigiKami pildi värvikanalite mikseri plugin +Comment[fa]=وصلۀ مخلوطکن مجراهای رنگ تصویر برای digiKam +Comment[fi]=Värikanavien sekoitussuhteiden muokkain +Comment[gl]=Un plugin de digiKam para misturar os canais de cores +Comment[hr]=digiKam dodatak za miješanje kanala boja +Comment[is]=Íforrit fyrir digiKam sem blandar litrásum mynda +Comment[it]=Plugin di mixer dei canali dei colori per digiKam +Comment[ja]=digiKam カラーチャンネルミキサープラグイン +Comment[nds]=digiKam-Mischermoduul för de Bild-Klöörkanaals +Comment[nl]=Digikam-plugin voor kanaalmixer +Comment[pa]=ਡਿਜ਼ੀਕੈਮ ਲਈ ਚਿੱਤਰ ਰੰਗ ਚੈਨਲ ਮਿਕਸਰ ਪਲੱਗਇਨ +Comment[pl]=Wtyczka do programu digiKam mieszająca kanały kolorów +Comment[pt]=Um 'plugin' do digiKam para misturar os canais de cores +Comment[pt_BR]=Plugin do mixer de canais de cor da imagem +Comment[ru]=Модуль микширования цветовых каналов для digiKam +Comment[sk]=digiKam plugin pre miešanie farebných kanálov obrázku +Comment[sr]=Прикључак миксете канала боја за digiKam +Comment[sr@Latn]=Priključak miksete kanala boja za digiKam +Comment[sv]=Digikam insticksprogram för att blanda bildfärgkanaler +Comment[tr]=digiKam için resim kanalları karıştıcı eklentisi +Comment[uk]=Втулок змішування каналів кольорів для digiKam +Comment[vi]=Phần bổ sung hoà kênh màu ảnh cho digiKam +Comment[xx]=xxImage color channels mixer plugin for digiKamxx + +X-TDE-Library=digikamimageplugin_channelmixer +author=Caulier Gilles, caulier dot gilles at gmail dot com diff --git a/src/imageplugins/channelmixer/digikamimageplugin_channelmixer_ui.rc b/src/imageplugins/channelmixer/digikamimageplugin_channelmixer_ui.rc new file mode 100644 index 00000000..1a004c96 --- /dev/null +++ b/src/imageplugins/channelmixer/digikamimageplugin_channelmixer_ui.rc @@ -0,0 +1,20 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui version="5" name="digikamimageplugin_channelmixer" > + + <MenuBar> + + <Menu name="Color"><text>&Color</text> + <Action name="imageplugin_channelmixer" /> + </Menu> + + </MenuBar> + + <ToolBar name="ToolBar" > + <text>Main Toolbar</text> + </ToolBar> + + <ActionProperties> + <Action name="imageplugin_channelmixer" /> + </ActionProperties> + +</kpartgui> diff --git a/src/imageplugins/channelmixer/imageplugin_channelmixer.cpp b/src/imageplugins/channelmixer/imageplugin_channelmixer.cpp new file mode 100644 index 00000000..19fe21a9 --- /dev/null +++ b/src/imageplugins/channelmixer/imageplugin_channelmixer.cpp @@ -0,0 +1,71 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2005-02-26 + * Description : image channels mixer. + * + * Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * + * 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, 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. + * + * ============================================================ */ + +// KDE includes. + +#include <tdelocale.h> +#include <kgenericfactory.h> +#include <klibloader.h> +#include <tdeaction.h> +#include <kcursor.h> + +// Local includes. + +#include "ddebug.h" +#include "channelmixertool.h" +#include "imageplugin_channelmixer.h" +#include "imageplugin_channelmixer.moc" + +using namespace DigikamChannelMixerImagesPlugin; + +K_EXPORT_COMPONENT_FACTORY(digikamimageplugin_channelmixer, + KGenericFactory<ImagePlugin_ChannelMixer>("digikamimageplugin_channelmixer")) + +ImagePlugin_ChannelMixer::ImagePlugin_ChannelMixer(TQObject *parent, const char*, + const TQStringList &) + : Digikam::ImagePlugin(parent, "ImagePlugin_ChannelMixer") +{ + m_channelMixerAction = new TDEAction(i18n("Channel Mixer..."), "channelmixer", + CTRL+Key_H, + this, TQ_SLOT(slotChannelMixer()), + actionCollection(), "imageplugin_channelmixer"); + + setXMLFile("digikamimageplugin_channelmixer_ui.rc"); + + DDebug() << "ImagePlugin_ChannelMixer plugin loaded" << endl; +} + +ImagePlugin_ChannelMixer::~ImagePlugin_ChannelMixer() +{ +} + +void ImagePlugin_ChannelMixer::setEnabledActions(bool enable) +{ + m_channelMixerAction->setEnabled(enable); +} + +void ImagePlugin_ChannelMixer::slotChannelMixer() +{ + ChannelMixerTool *cm = new ChannelMixerTool(this); + loadTool(cm); +} diff --git a/src/imageplugins/channelmixer/imageplugin_channelmixer.h b/src/imageplugins/channelmixer/imageplugin_channelmixer.h new file mode 100644 index 00000000..444006ab --- /dev/null +++ b/src/imageplugins/channelmixer/imageplugin_channelmixer.h @@ -0,0 +1,56 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2005-02-26 + * Description : image channels mixer. + * + * Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * + * 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, 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. + * + * ============================================================ */ + +#ifndef IMAGEPLUGIN_CHANNELMIXER_H +#define IMAGEPLUGIN_CHANNELMIXER_H + +// Digikam includes. + +#include "imageplugin.h" +#include "digikam_export.h" + +class TDEAction; + +class DIGIKAMIMAGEPLUGINS_EXPORT ImagePlugin_ChannelMixer : public Digikam::ImagePlugin +{ + TQ_OBJECT + + +public: + + ImagePlugin_ChannelMixer(TQObject *parent, const char* name, + const TQStringList &args); + ~ImagePlugin_ChannelMixer(); + + void setEnabledActions(bool enable); + +private slots: + + void slotChannelMixer(); + +private: + + TDEAction *m_channelMixerAction; +}; + +#endif /* IMAGEPLUGIN_CHANNELMIXER_H */ |