/* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2005-03-11 * Description : a digiKam image editor plugin to correct * image white balance * * Copyright (C) 2005-2008 by Gilles Caulier * Copyright (C) 2008 by Guillaume Castagnino * * 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. * * ============================================================ */ // TQt includes. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // KDE includes. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // LibKDcraw includes. #include #include // Digikam includes. #include "colorgradientwidget.h" #include "daboutdata.h" #include "dcolor.h" #include "ddebug.h" #include "dimg.h" #include "dimgimagefilters.h" #include "editortoolsettings.h" #include "histogramwidget.h" #include "imagehistogram.h" #include "imageiface.h" #include "imagewidget.h" #include "whitebalance.h" // Local includes. #include "whitebalancetool.h" #include "whitebalancetool.moc" using namespace KDcrawIface; using namespace Digikam; namespace DigikamWhiteBalanceImagesPlugin { WhiteBalanceTool::WhiteBalanceTool(TQObject* parent) : EditorTool(parent) { setName("whitebalance"); setToolName(i18n("White Balance")); setToolIcon(SmallIcon("whitebalance")); m_destinationPreviewData = 0; // ------------------------------------------------------------- m_previewWidget = new ImageWidget("whitebalance Tool", 0, i18n("

You can see here the image's white-balance " "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); TQVBoxLayout* layout2 = new TQVBoxLayout(m_gboxSettings->plainPage(), m_gboxSettings->spacingHint()); TQGridLayout *grid = new TQGridLayout(layout2, 2, 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("Luminosity") ); m_channelCB->insertItem( i18n("Red") ); m_channelCB->insertItem( i18n("Green") ); m_channelCB->insertItem( i18n("Blue") ); TQWhatsThis::add( m_channelCB, i18n("

Select the histogram channel to display here:

" "Luminosity: display the image's luminosity values.

" "Red: display the red image-channel values.

" "Green: display the green image-channel values.

" "Blue: display the blue image-channel values.

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

Select the histogram scale here.

" "If the image's maximal counts are small, you can use the linear scale.

" "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( "

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( "

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("

Here you can see the target preview image histogram " "drawing of the selected image channel. This one is " "re-computed at any filter settings changes.")); TQLabel *space = new TQLabel(histoBox); space->setFixedHeight(1); m_hGradient = new ColorGradientWidget( ColorGradientWidget::Horizontal, 10, histoBox ); m_hGradient->setColors( TQColor( "black" ), TQColor( "white" ) ); grid->addMultiCellLayout(l1, 0, 0, 0, 4); grid->addMultiCellWidget(histoBox, 1, 2, 0, 4); grid->setMargin(m_gboxSettings->spacingHint()); grid->setSpacing(m_gboxSettings->spacingHint()); // ------------------------------------------------------------- TQGridLayout *grid2 = new TQGridLayout(layout2, 13, 5); m_temperatureLabel = new KActiveLabel(i18n("Color Temperature " " (K): "), m_gboxSettings->plainPage()); m_adjTemperatureLabel = new TQLabel(i18n("Adjustment:"), m_gboxSettings->plainPage()); m_temperatureInput = new RDoubleNumInput(m_gboxSettings->plainPage()); m_temperatureInput->setPrecision(1); m_temperatureInput->setRange(1750.0, 12000.0, 10.0); m_temperatureInput->setDefaultValue(6500.0); TQWhatsThis::add( m_temperatureInput, i18n("

Set here the white balance color temperature in Kelvin.")); m_temperaturePresetLabel = new TQLabel(i18n("Preset:"), m_gboxSettings->plainPage()); m_temperaturePresetCB = new RComboBox(m_gboxSettings->plainPage()); m_temperaturePresetCB->insertItem(i18n("Candle")); m_temperaturePresetCB->insertItem(i18n("40W Lamp")); m_temperaturePresetCB->insertItem(i18n("100W Lamp")); m_temperaturePresetCB->insertItem(i18n("200W Lamp")); m_temperaturePresetCB->insertItem(i18n("Sunrise")); m_temperaturePresetCB->insertItem(i18n("Studio Lamp")); m_temperaturePresetCB->insertItem(i18n("Moonlight")); m_temperaturePresetCB->insertItem(i18n("Neutral")); m_temperaturePresetCB->insertItem(i18n("Daylight D50")); m_temperaturePresetCB->insertItem(i18n("Photo Flash")); m_temperaturePresetCB->insertItem(i18n("Sun")); m_temperaturePresetCB->insertItem(i18n("Xenon Lamp")); m_temperaturePresetCB->insertItem(i18n("Daylight D65")); m_temperaturePresetCB->insertItem(i18n("None")); m_temperaturePresetCB->setDefaultItem(DaylightD65); TQWhatsThis::add( m_temperaturePresetCB, i18n("

Select the white balance color temperature " "preset to use here:

" "Candle: candle light (1850K).

" "40W Lamp: 40 Watt incandescent lamp (2680K).

" "100W Lamp: 100 Watt incandescent lamp (2800K).

" "200W Lamp: 200 Watt incandescent lamp (3000K).

" "Sunrise: sunrise or sunset light (3200K).

" "Studio Lamp: tungsten lamp used in photo studio " "or light at 1 hour from dusk/dawn (3400K).

" "Moonlight: moon light (4100K).

" "Neutral: neutral color temperature (4750K).

" "Daylight D50: sunny daylight around noon (5000K).

" "Photo Flash: electronic photo flash (5500K).

" "Sun: effective sun temperature (5770K).

" "Xenon Lamp: xenon lamp or light arc (6420K).

" "Daylight D65: overcast sky light (6500K).

" "None: no preset value.")); m_pickTemperature = new TQPushButton(m_gboxSettings->plainPage()); TDEGlobal::dirs()->addResourceType("color-picker-grey", TDEGlobal::dirs()->kde_default("data") + "digikam/data"); directory = TDEGlobal::dirs()->findResourceDir("color-picker-grey", "color-picker-grey.png"); m_pickTemperature->setPixmap( TQPixmap( directory + "color-picker-grey.png" ) ); m_pickTemperature->setToggleButton(true); TQToolTip::add( m_pickTemperature, i18n( "Temperature tone color picker." ) ); TQWhatsThis::add( m_pickTemperature, i18n("

With this button, you can pick the color from original " "image used to set white color balance temperature and " "green component.")); KSeparator *line = new KSeparator(Horizontal, m_gboxSettings->plainPage()); // ------------------------------------------------------------- m_blackLabel = new TQLabel(i18n("Black point:"), m_gboxSettings->plainPage()); m_blackInput = new RDoubleNumInput(m_gboxSettings->plainPage()); m_blackInput->setPrecision(2); m_blackInput->setRange(0.0, 0.05, 0.01); m_blackInput->setDefaultValue(0.0); TQWhatsThis::add( m_blackInput, i18n("

Set here the black level value.")); m_darkLabel = new TQLabel(i18n("Shadows:"), m_gboxSettings->plainPage()); m_darkInput = new RDoubleNumInput(m_gboxSettings->plainPage()); m_darkInput->setPrecision(2); m_darkInput->setRange(0.0, 1.0, 0.01); m_darkInput->setDefaultValue(0.5); TQWhatsThis::add( m_darkInput, i18n("

Set here the shadows noise suppresion level.")); m_saturationLabel = new TQLabel(i18n("Saturation:"), m_gboxSettings->plainPage()); m_saturationInput = new RDoubleNumInput(m_gboxSettings->plainPage()); m_saturationInput->setPrecision(2); m_saturationInput->setRange(0.0, 2.0, 0.01); m_saturationInput->setDefaultValue(1.0); TQWhatsThis::add( m_saturationInput, i18n("

Set here the saturation value.")); m_gammaLabel = new TQLabel(i18n("Gamma:"), m_gboxSettings->plainPage()); m_gammaInput = new RDoubleNumInput(m_gboxSettings->plainPage()); m_gammaInput->setPrecision(2); m_gammaInput->setRange(0.1, 3.0, 0.01); m_gammaInput->setDefaultValue(1.0); TQWhatsThis::add( m_gammaInput, i18n("

Set here the gamma correction value.")); m_greenLabel = new TQLabel(i18n("Green:"), m_gboxSettings->plainPage()); m_greenInput = new RDoubleNumInput(m_gboxSettings->plainPage()); m_greenInput->setPrecision(2); m_greenInput->setRange(0.2, 2.5, 0.01); m_greenInput->setDefaultValue(1.0); TQWhatsThis::add(m_greenInput, i18n("

Set here the green component to set magenta color " "cast removal level.")); KSeparator *line2 = new KSeparator(Horizontal, m_gboxSettings->plainPage()); // ------------------------------------------------------------- m_exposureLabel = new KActiveLabel(i18n("Exposure Compensation " " (E.V): "), m_gboxSettings->plainPage()); m_mainExposureLabel = new TQLabel(i18n("Main:"), m_gboxSettings->plainPage()); m_autoAdjustExposure = new TQPushButton(m_gboxSettings->plainPage()); m_autoAdjustExposure->setPixmap(kapp->iconLoader()->loadIcon("run", (KIcon::Group)KIcon::Toolbar)); TQToolTip::add( m_autoAdjustExposure, i18n( "Auto exposure adjustments" ) ); TQWhatsThis::add( m_autoAdjustExposure, i18n("

With this button, you can automatically adjust Exposure " "and Black Point values.")); m_mainExposureInput = new RDoubleNumInput(m_gboxSettings->plainPage()); m_mainExposureInput->setPrecision(2); m_mainExposureInput->setRange(-6.0, 8.0, 0.1); m_mainExposureInput->setDefaultValue(0.0); TQWhatsThis::add( m_mainExposureInput, i18n("

Set here the main exposure compensation value in E.V.")); m_fineExposureLabel = new TQLabel(i18n("Fine:"), m_gboxSettings->plainPage()); m_fineExposureInput = new RDoubleNumInput(m_gboxSettings->plainPage()); m_fineExposureInput->setPrecision(2); m_fineExposureInput->setRange(-0.5, 0.5, 0.01); m_fineExposureInput->setDefaultValue(0.0); TQWhatsThis::add( m_fineExposureInput, i18n("

This value in E.V will be added to main exposure " "compensation value to set fine exposure adjustment.")); // ------------------------------------------------------------- grid2->addMultiCellWidget(m_temperatureLabel, 0, 0, 0, 5); grid2->addMultiCellWidget(m_adjTemperatureLabel, 1, 1, 0, 0); grid2->addMultiCellWidget(m_pickTemperature, 1, 1, 1, 1); grid2->addMultiCellWidget(m_temperatureInput, 1, 1, 2, 5); grid2->addMultiCellWidget(m_temperaturePresetLabel, 2, 2, 0, 0); grid2->addMultiCellWidget(m_temperaturePresetCB, 2, 2, 2, 5); grid2->addMultiCellWidget(line, 3, 3, 0, 5); grid2->addMultiCellWidget(m_blackLabel, 4, 4, 0, 0); grid2->addMultiCellWidget(m_blackInput, 4, 4, 1, 5); grid2->addMultiCellWidget(m_darkLabel, 5, 5, 0, 0); grid2->addMultiCellWidget(m_darkInput, 5, 5, 1, 5); grid2->addMultiCellWidget(m_saturationLabel, 6, 6, 0, 0); grid2->addMultiCellWidget(m_saturationInput, 6, 6, 1, 5); grid2->addMultiCellWidget(m_gammaLabel, 7, 7, 0, 0); grid2->addMultiCellWidget(m_gammaInput, 7, 7, 1, 5); grid2->addMultiCellWidget(m_greenLabel, 8, 8, 0, 0); grid2->addMultiCellWidget(m_greenInput, 8, 8, 1, 5); grid2->addMultiCellWidget(line2, 9, 9, 0, 5); grid2->addMultiCellWidget(m_exposureLabel, 10, 10, 0, 5); grid2->addMultiCellWidget(m_mainExposureLabel, 11, 11, 0, 0); grid2->addMultiCellWidget(m_autoAdjustExposure, 11, 11, 1, 1); grid2->addMultiCellWidget(m_mainExposureInput, 11, 11, 2, 5); grid2->addMultiCellWidget(m_fineExposureLabel, 12, 12, 0, 1); grid2->addMultiCellWidget(m_fineExposureInput, 12, 12, 2, 5); grid2->setRowStretch(13, 10); grid2->setMargin(m_gboxSettings->spacingHint()); grid2->setSpacing(m_gboxSettings->spacingHint()); setToolSettings(m_gboxSettings); init(); // ------------------------------------------------------------- connect(m_channelCB, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotChannelChanged(int))); connect(m_scaleBG, TQT_SIGNAL(released(int)), this, TQT_SLOT(slotScaleChanged(int))); connect(m_previewWidget, TQT_SIGNAL(spotPositionChangedFromOriginal(const Digikam::DColor&, const TQPoint&)), this, TQT_SLOT(slotColorSelectedFromOriginal(const Digikam::DColor&))); connect(m_previewWidget, TQT_SIGNAL(spotPositionChangedFromTarget(const Digikam::DColor&, const TQPoint&)), this, TQT_SLOT(slotColorSelectedFromTarget(const Digikam::DColor&))); connect(m_previewWidget, TQT_SIGNAL(signalResized()), this, TQT_SLOT(slotEffect())); // ------------------------------------------------------------- // Correction Filter Slider controls. connect(m_temperaturePresetCB, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotTemperaturePresetChanged(int))); connect(m_temperatureInput, TQT_SIGNAL(valueChanged (double)), this, TQT_SLOT(slotTemperatureChanged(double))); connect(m_darkInput, TQT_SIGNAL(valueChanged (double)), this, TQT_SLOT(slotTimer())); connect(m_blackInput, TQT_SIGNAL(valueChanged (double)), this, TQT_SLOT(slotTimer())); connect(m_mainExposureInput, TQT_SIGNAL(valueChanged (double)), this, TQT_SLOT(slotTimer())); connect(m_fineExposureInput, TQT_SIGNAL(valueChanged (double)), this, TQT_SLOT(slotTimer())); connect(m_gammaInput, TQT_SIGNAL(valueChanged (double)), this, TQT_SLOT(slotTimer())); connect(m_saturationInput, TQT_SIGNAL(valueChanged (double)), this, TQT_SLOT(slotTimer())); connect(m_greenInput, TQT_SIGNAL(valueChanged (double)), this, TQT_SLOT(slotTimer())); // ------------------------------------------------------------- // Bouttons slots. connect(m_autoAdjustExposure, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotAutoAdjustExposure())); connect(m_pickTemperature, TQT_SIGNAL(released()), this, TQT_SLOT(slotPickerColorButtonActived())); } WhiteBalanceTool::~WhiteBalanceTool() { if (m_destinationPreviewData) delete [] m_destinationPreviewData; } void WhiteBalanceTool::slotTemperatureChanged(double temperature) { switch((uint)temperature) { case 1850: m_temperaturePresetCB->setCurrentItem(Candle); break; case 2680: m_temperaturePresetCB->setCurrentItem(Lamp40W); break; case 2800: m_temperaturePresetCB->setCurrentItem(Lamp100W); break; case 3000: m_temperaturePresetCB->setCurrentItem(Lamp200W); break; case 3200: m_temperaturePresetCB->setCurrentItem(Sunrise); break; case 3400: m_temperaturePresetCB->setCurrentItem(StudioLamp); break; case 4100: m_temperaturePresetCB->setCurrentItem(MoonLight); break; case 4750: m_temperaturePresetCB->setCurrentItem(Neutral); break; case 5000: m_temperaturePresetCB->setCurrentItem(DaylightD50); break; case 5500: m_temperaturePresetCB->setCurrentItem(Flash); break; case 5770: m_temperaturePresetCB->setCurrentItem(Sun); break; case 6420: m_temperaturePresetCB->setCurrentItem(XeonLamp); break; case 6500: m_temperaturePresetCB->setCurrentItem(DaylightD65); break; default: m_temperaturePresetCB->setCurrentItem(None); break; } slotTimer(); } void WhiteBalanceTool::slotTemperaturePresetChanged(int tempPreset) { switch(tempPreset) { case Candle: m_temperatureInput->setValue(1850.0); break; case Lamp40W: m_temperatureInput->setValue(2680.0); break; case Lamp100W: m_temperatureInput->setValue(2800.0); break; case Lamp200W: m_temperatureInput->setValue(3000.0); break; case Sunrise: m_temperatureInput->setValue(3200.0); break; case StudioLamp: m_temperatureInput->setValue(3400.0); break; case MoonLight: m_temperatureInput->setValue(4100.0); break; case Neutral: m_temperatureInput->setValue(4750.0); break; case DaylightD50: m_temperatureInput->setValue(5000.0); break; case Flash: m_temperatureInput->setValue(5500.0); break; case Sun: m_temperatureInput->setValue(5770.0); break; case XeonLamp: m_temperatureInput->setValue(6420.0); break; case DaylightD65: m_temperatureInput->setValue(6500.0); break; default: // None. break; } slotEffect(); } void WhiteBalanceTool::slotPickerColorButtonActived() { // Save previous rendering mode and toggle to original image. m_currentPreviewMode = m_previewWidget->getRenderingPreviewMode(); m_previewWidget->setRenderingPreviewMode(ImageGuideWidget::PreviewOriginalImage); } void WhiteBalanceTool::slotColorSelectedFromOriginal(const DColor &color) { if ( m_pickTemperature->isOn() ) { DColor dc = color; TQColor tc = dc.getTQColor(); double temperatureLevel, greenLevel; WhiteBalance::autoWBAdjustementFromColor(tc, temperatureLevel, greenLevel); m_temperatureInput->setValue(temperatureLevel); m_greenInput->setValue(greenLevel); m_pickTemperature->setOn(false); } else return; // restore previous rendering mode. m_previewWidget->setRenderingPreviewMode(m_currentPreviewMode); slotEffect(); } void WhiteBalanceTool::slotColorSelectedFromTarget(const DColor& color) { m_histogramWidget->setHistogramGuideByColor(color); } void WhiteBalanceTool::slotScaleChanged(int scale) { m_histogramWidget->m_scaleType = scale; m_histogramWidget->repaint(false); } void WhiteBalanceTool::slotChannelChanged(int channel) { switch(channel) { case LuminosityChannel: m_histogramWidget->m_channelType = HistogramWidget::ValueHistogram; m_hGradient->setColors( TQColor( "black" ), TQColor( "white" ) ); break; case RedChannel: m_histogramWidget->m_channelType = HistogramWidget::RedChannelHistogram; m_hGradient->setColors( TQColor( "black" ), TQColor( "red" ) ); break; case GreenChannel: m_histogramWidget->m_channelType = HistogramWidget::GreenChannelHistogram; m_hGradient->setColors( TQColor( "black" ), TQColor( "green" ) ); break; case BlueChannel: m_histogramWidget->m_channelType = HistogramWidget::BlueChannelHistogram; m_hGradient->setColors( TQColor( "black" ), TQColor( "blue" ) ); break; } m_histogramWidget->repaint(false); } void WhiteBalanceTool::slotAutoAdjustExposure() { kapp->setOverrideCursor( KCursor::waitCursor() ); ImageIface* iface = m_previewWidget->imageIface(); uchar *data = iface->getOriginalImage(); int width = iface->originalWidth(); int height = iface->originalHeight(); bool sb = iface->originalSixteenBit(); double blackLevel; double exposureLevel; WhiteBalance::autoExposureAdjustement(data, width, height, sb, blackLevel, exposureLevel); delete [] data; m_blackInput->setValue(blackLevel); m_mainExposureInput->setValue(exposureLevel); m_fineExposureInput->setValue(0.0); kapp->restoreOverrideCursor(); slotEffect(); } void WhiteBalanceTool::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)]; double temperature = m_temperatureInput->value(); double dark = m_darkInput->value(); double black = m_blackInput->value(); double mainExposure = m_mainExposureInput->value(); double fineExposure = m_fineExposureInput->value(); double gamma = m_gammaInput->value(); double saturation = m_saturationInput->value(); double green = m_greenInput->value(); WhiteBalance wbFilter(sb); wbFilter.whiteBalance(data, w, h, sb, black, mainExposure + fineExposure, temperature, green, dark, gamma, saturation); 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 WhiteBalanceTool::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(); double temperature = m_temperatureInput->value(); double dark = m_darkInput->value(); double black = m_blackInput->value(); double mainExposure = m_mainExposureInput->value(); double fineExposure = m_fineExposureInput->value(); double gamma = m_gammaInput->value(); double saturation = m_saturationInput->value(); double green = m_greenInput->value(); WhiteBalance wbFilter(sb); wbFilter.whiteBalance(data, w, h, sb, black, mainExposure + fineExposure, temperature, green, dark, gamma, saturation); iface->putOriginalImage(i18n("White Balance"), data); delete [] data; kapp->restoreOverrideCursor(); } void WhiteBalanceTool::slotResetSettings() { m_blackInput->blockSignals(true); m_darkInput->blockSignals(true); m_fineExposureInput->blockSignals(true); m_gammaInput->blockSignals(true); m_greenInput->blockSignals(true); m_mainExposureInput->blockSignals(true); m_saturationInput->blockSignals(true); m_temperatureInput->blockSignals(true); m_temperaturePresetCB->blockSignals(true); // Neutral color temperature settings is D65 m_blackInput->slotReset(); m_darkInput->slotReset(); m_fineExposureInput->slotReset(); m_gammaInput->slotReset(); m_greenInput->slotReset(); m_mainExposureInput->slotReset(); m_saturationInput->slotReset(); m_temperaturePresetCB->slotReset(); slotTemperaturePresetChanged(m_temperaturePresetCB->defaultItem()); m_temperatureInput->slotReset(); m_previewWidget->resetSpotPosition(); m_channelCB->setCurrentItem(LuminosityChannel); slotChannelChanged(LuminosityChannel); m_histogramWidget->reset(); m_blackInput->blockSignals(false); m_darkInput->blockSignals(false); m_fineExposureInput->blockSignals(false); m_gammaInput->blockSignals(false); m_greenInput->blockSignals(false); m_mainExposureInput->blockSignals(false); m_saturationInput->blockSignals(false); m_temperatureInput->blockSignals(false); m_temperaturePresetCB->blockSignals(false); slotEffect(); } void WhiteBalanceTool::readSettings() { TDEConfig* config = kapp->config(); config->setGroup("whitebalance Tool"); m_channelCB->setCurrentItem(config->readNumEntry("Histogram Channel", 0)); // Luminosity. m_scaleBG->setButton(config->readNumEntry("Histogram Scale", HistogramWidget::LogScaleHistogram)); m_darkInput->setValue(config->readDoubleNumEntry("Dark",m_darkInput->defaultValue())); m_blackInput->setValue(config->readDoubleNumEntry("Black", m_blackInput->defaultValue())); m_mainExposureInput->setValue(config->readDoubleNumEntry("MainExposure", m_mainExposureInput->defaultValue())); m_fineExposureInput->setValue(config->readDoubleNumEntry("FineExposure", m_fineExposureInput->defaultValue())); m_gammaInput->setValue(config->readDoubleNumEntry("Gamma", m_gammaInput->defaultValue())); m_saturationInput->setValue(config->readDoubleNumEntry("Saturation", m_saturationInput->defaultValue())); m_greenInput->setValue(config->readDoubleNumEntry("Green", m_greenInput->defaultValue())); m_temperatureInput->setValue(config->readDoubleNumEntry("Temperature", m_temperatureInput->defaultValue())); slotTemperatureChanged(m_temperatureInput->value()); m_histogramWidget->reset(); slotChannelChanged(m_channelCB->currentItem()); slotScaleChanged(m_scaleBG->selectedId()); } void WhiteBalanceTool::writeSettings() { TDEConfig* config = kapp->config(); config->setGroup("whitebalance Tool"); config->writeEntry("Histogram Channel", m_channelCB->currentItem()); config->writeEntry("Histogram Scale", m_scaleBG->selectedId()); config->writeEntry("Dark", m_darkInput->value()); config->writeEntry("Black", m_blackInput->value()); config->writeEntry("MainExposure", m_mainExposureInput->value()); config->writeEntry("FineExposure", m_fineExposureInput->value()); config->writeEntry("Gamma", m_gammaInput->value()); config->writeEntry("Saturation", m_saturationInput->value()); config->writeEntry("Green", m_greenInput->value()); config->writeEntry("Temperature", m_temperatureInput->value()); m_previewWidget->writeSettings(); config->sync(); } void WhiteBalanceTool::slotLoadSettings() { KURL loadWhiteBalanceFile = KFileDialog::getOpenURL(TDEGlobalSettings::documentPath(), TQString( "*" ), kapp->activeWindow(), TQString( i18n("White Color Balance Settings File to Load")) ); if( loadWhiteBalanceFile.isEmpty() ) return; TQFile file(loadWhiteBalanceFile.path()); if ( file.open(IO_ReadOnly) ) { TQTextStream stream( &file ); if ( stream.readLine() != "# White Color Balance Configuration File V2" ) { KMessageBox::error(kapp->activeWindow(), i18n("\"%1\" is not a White Color Balance settings text file.") .arg(loadWhiteBalanceFile.fileName())); file.close(); return; } blockSignals(true); m_temperatureInput->setValue( stream.readLine().toDouble() ); m_darkInput->setValue( stream.readLine().toDouble() ); m_blackInput->setValue( stream.readLine().toDouble() ); m_mainExposureInput->setValue( stream.readLine().toDouble() ); m_fineExposureInput->setValue( stream.readLine().toDouble() ); m_gammaInput->setValue( stream.readLine().toDouble() ); m_saturationInput->setValue( stream.readLine().toDouble() ); m_greenInput->setValue( stream.readLine().toDouble() ); m_histogramWidget->reset(); blockSignals(false); slotEffect(); } else KMessageBox::error(kapp->activeWindow(), i18n("Cannot load settings from the White Color Balance text file.")); file.close(); } void WhiteBalanceTool::slotSaveAsSettings() { KURL saveWhiteBalanceFile = KFileDialog::getSaveURL(TDEGlobalSettings::documentPath(), TQString( "*" ), kapp->activeWindow(), TQString( i18n("White Color Balance Settings File to Save")) ); if( saveWhiteBalanceFile.isEmpty() ) return; TQFile file(saveWhiteBalanceFile.path()); if ( file.open(IO_WriteOnly) ) { TQTextStream stream( &file ); stream << "# White Color Balance Configuration File V2\n"; stream << m_temperatureInput->value() << "\n"; stream << m_darkInput->value() << "\n"; stream << m_blackInput->value() << "\n"; stream << m_mainExposureInput->value() << "\n"; stream << m_fineExposureInput->value() << "\n"; stream << m_gammaInput->value() << "\n"; stream << m_saturationInput->value() << "\n"; stream << m_greenInput->value() << "\n"; } else KMessageBox::error(kapp->activeWindow(), i18n("Cannot save settings to the White Color Balance text file.")); file.close(); } } // NameSpace DigikamWhiteBalanceImagesPlugin