Engauge Digitizer 2
Loading...
Searching...
No Matches
DlgSettingsColorFilter.cpp
Go to the documentation of this file.
1/******************************************************************************************************
2 * (C) 2014 markummitchell@github.com. This file is part of Engauge Digitizer, which is released *
3 * under GNU General Public License version 2 (GPLv2) or (at your option) any later version. See file *
4 * LICENSE or go to gnu.org/licenses for details. Distribution requires prior written permission. *
5 ******************************************************************************************************/
6
7#include "CmdMediator.h"
9#include "ColorFilter.h"
11#include "ColorConstants.h"
12#include "DlgFilterThread.h"
14#include "EngaugeAssert.h"
15#include "Logger.h"
16#include "MainWindow.h"
17#include <QComboBox>
18#include <QDebug>
19#include <QGraphicsLineItem>
20#include <QGraphicsScene>
21#include <QGridLayout>
22#include <QImage>
23#include <QLabel>
24#include <qmath.h>
25#include <QPixmap>
26#include <QRadioButton>
27#include <QRgb>
28#include "ViewPreview.h"
29#include "ViewProfile.h"
30#include "ViewProfileDivider.h"
31#include "ViewProfileScale.h"
32
34const int MINIMUM_HEIGHT = 500;
35
37 DlgSettingsAbstractBase (tr ("Color Filter"),
38 "DlgSettingsColorFilter",
39 mainWindow),
40 m_scenePreview (nullptr),
41 m_viewPreview (nullptr),
42 m_filterThread (nullptr),
43 m_modelColorFilterBefore (nullptr),
44 m_modelColorFilterAfter (nullptr)
45{
46 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::DlgSettingsColorFilter";
47
48 QWidget *subPanel = createSubPanel ();
49 finishPanel (subPanel,
51}
52
54{
55 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::~DlgSettingsColorFilter";
56
57 delete m_filterThread;
58}
59
60void DlgSettingsColorFilter::createControls (QGridLayout *layout, int &row)
61{
62 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::createControls";
63
64 QLabel *labelCurve = new QLabel (QString ("%1:").arg (tr ("Curve Name")));
65 layout->addWidget (labelCurve, row++, 1);
66
67 m_cmbCurveName = new QComboBox ();
68 m_cmbCurveName->setWhatsThis (tr ("Name of the curve that is currently selected for editing"));
69 connect (m_cmbCurveName, SIGNAL (activated (const QString &)), this, SLOT (slotCurveName (const QString &))); // activated() ignores code changes
70 layout->addWidget (m_cmbCurveName, row++, 1);
71
72 QLabel *labelProfile = new QLabel (QString ("%1:").arg (tr ("Filter mode")));
73 layout->addWidget (labelProfile, row++, 1);
74
75 m_btnIntensity = new QRadioButton (colorFilterModeToString (COLOR_FILTER_MODE_INTENSITY));
76 m_btnIntensity->setWhatsThis (tr ("Filter the original image into black and white pixels using the Intensity parameter, "
77 "to hide unimportant information and emphasize important information.\n\n"
78 "The Intensity value of a pixel is computed from the red, green "
79 "and blue components as I = squareroot (R * R + G * G + B * B)"));
80 connect (m_btnIntensity, SIGNAL (released ()), this, SLOT (slotIntensity ()));
81 layout->addWidget (m_btnIntensity, row++, 1);
82
83 m_btnForeground = new QRadioButton (colorFilterModeToString (COLOR_FILTER_MODE_FOREGROUND));
84 m_btnForeground->setWhatsThis (tr ("Filter the original image into black and white pixels by isolating the foreground from the background, "
85 "to hide unimportant information and emphasize important information.\n\n"
86 "The background color is shown on the left side of the scale bar.\n\n"
87 "The distance of any color (R, G, B) from the background color (Rb, Gb, Bb) is computed as "
88 "F = squareroot ((R - Rb) * (R - Rb) + (G - Gb) * (G - Gb) + (B - Bb)). On the left end of the "
89 "scale, the foreground distance value is zero, and it increases linearly to the maximum on the far right."));
90 connect (m_btnForeground, SIGNAL (released ()), this, SLOT (slotForeground ()));
91 layout->addWidget (m_btnForeground, row++, 1);
92
93 m_btnHue = new QRadioButton (colorFilterModeToString (COLOR_FILTER_MODE_HUE));
94 m_btnHue->setWhatsThis (tr ("Filter the original image into black and white pixels using the Hue component of the "
95 "Hue, Saturation and Value (HSV) color components, "
96 "to hide unimportant information and emphasize important information."));
97 connect (m_btnHue, SIGNAL (released ()), this, SLOT (slotHue ()));
98 layout->addWidget (m_btnHue, row++, 1);
99
100 m_btnSaturation = new QRadioButton (colorFilterModeToString (COLOR_FILTER_MODE_SATURATION));
101 m_btnSaturation->setWhatsThis (tr ("Filter the original image into black and white pixels using the Saturation component of the "
102 "Hue, Saturation and Value (HSV) color components, "
103 "to hide unimportant information and emphasize important information."));
104 connect (m_btnSaturation, SIGNAL (released ()), this, SLOT (slotSaturation ()));
105 layout->addWidget (m_btnSaturation, row++, 1);
106
107 m_btnValue = new QRadioButton (colorFilterModeToString (COLOR_FILTER_MODE_VALUE));
108 m_btnValue->setWhatsThis (tr ("Filter the original image into black and white pixels using the Value component of the "
109 "Hue, Saturation and Value (HSV) color components, "
110 "to hide unimportant information and emphasize important information.\n\n"
111 "The Value component is also called the Lightness."));
112 connect (m_btnValue, SIGNAL (released ()), this, SLOT (slotValue ()));
113 layout->addWidget (m_btnValue, row++, 1);
114}
115
117{
118}
119
120void DlgSettingsColorFilter::createPreview (QGridLayout *layout, int &row)
121{
122 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::createPreview";
123
124 QLabel *labelPreview = new QLabel (tr ("Preview"));
125 layout->addWidget (labelPreview, row++, 0, 1, 5);
126
127 m_scenePreview = new QGraphicsScene (this);
128 m_viewPreview = new ViewPreview (m_scenePreview,
130 this);
131 m_viewPreview->setWhatsThis (tr ("Preview window that shows how current settings affect the filtering of the original image."));
132 m_viewPreview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
133 m_viewPreview->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
134 m_viewPreview->setMinimumHeight (MINIMUM_PREVIEW_HEIGHT);
135 m_viewPreview->setRenderHint(QPainter::Antialiasing);
136
137 layout->addWidget (m_viewPreview, row++, 0, 1, 5);
138}
139
140void DlgSettingsColorFilter::createProfileAndScale (QGridLayout *layout, int &row)
141{
142 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::createProfileAndScale";
143
144 const int MINIMUM_VIEW_PROFILE_WIDTH = 70;
145
146 QLabel *labelProfile = new QLabel (tr ("Filter Parameter Histogram Profile"));
147 layout->addWidget (labelProfile, row++, 3);
148
149 m_sceneProfile = new QGraphicsScene;
150 m_sceneProfile->setSceneRect(0, 0, PROFILE_SCENE_WIDTH (), PROFILE_SCENE_HEIGHT ());
151
152 m_viewProfile = new ViewProfile (m_sceneProfile,
153 MINIMUM_VIEW_PROFILE_WIDTH);
154 m_viewProfile->setWhatsThis (tr ("Histogram profile of the selected filter parameter. The two Dividers can be moved back and forth to adjust "
155 "the range of filter parameter values that will be included in the filtered image. The clear portion will "
156 "be included, and the shaded portion will be excluded."));
157 layout->addWidget (m_viewProfile, row, 3, PROFILE_HEIGHT_IN_ROWS (), 1);
158 row += PROFILE_HEIGHT_IN_ROWS ();
159
160 m_scale = new ViewProfileScale (MINIMUM_VIEW_PROFILE_WIDTH);
161 m_scale->setWhatsThis (tr ("This read-only box displays a graphical representation of the horizontal axis in the histogram profile above."));
162 m_scale->setAutoFillBackground(true);
163 layout->addWidget (m_scale, row++, 3, 1, 1);
164}
165
167{
168 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::createSubPanel";
169
170 const int EMPTY_COLUMN_WIDTH = 40;
171
172 QWidget *subPanel = new QWidget ();
173 QGridLayout *layout = new QGridLayout (subPanel);
174 subPanel->setLayout (layout);
175
176 layout->setColumnStretch(0, 0); // Empty column
177 layout->setColumnMinimumWidth(0, EMPTY_COLUMN_WIDTH);
178 layout->setColumnStretch(1, 0); // Radio buttons
179 layout->setColumnMinimumWidth(1, 210);
180 layout->setColumnStretch(2, 0); // Empty column to put some space between previous and next columns, so they are not too close
181 layout->setColumnMinimumWidth(2, 15);
182 layout->setColumnStretch(3, 1); // Profile
183 layout->setColumnMinimumWidth(4, EMPTY_COLUMN_WIDTH); // Empty column
184 layout->setColumnStretch(4, 0);
185
186 int rowLeft = 0, rowRight = 0;
187 createControls (layout, rowLeft);
188 createProfileAndScale (layout, rowRight);
189
190 int row = qMax (rowLeft, rowRight);
191 createPreview (layout, row);
192
193 return subPanel;
194}
195
196QRgb DlgSettingsColorFilter::createThread ()
197{
198 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::createThread";
199
200 // Get background color
201 QImage image = cmdMediator().document().pixmap().toImage();
202 ColorFilter filter;
203 QRgb rgbBackground = filter.marginColor(&image);
204
205 // Only create thread once
206 if (m_filterThread == nullptr) {
207
208 m_filterThread = new DlgFilterThread (cmdMediator().document().pixmap(),
209 rgbBackground,
210 *this);
211 m_filterThread->start(); // Now that thread is started, we can use signalApplyFilter
212 }
213
214 return rgbBackground;
215}
216
218{
219 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::handleOk";
220
222 cmdMediator ().document(),
223 *m_modelColorFilterBefore,
224 *m_modelColorFilterAfter);
225 cmdMediator ().push (cmd);
226
227 hide ();
228}
229
231{
232 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::load";
233
235
236 // Flush old data
237 delete m_modelColorFilterBefore;
238 delete m_modelColorFilterAfter;
239
240 // Save new data
241 m_modelColorFilterBefore = new DocumentModelColorFilter (cmdMediator.document().modelColorFilter());
242 m_modelColorFilterAfter = new DocumentModelColorFilter (cmdMediator.document().modelColorFilter());
243
244 // Populate controls. First load curve name combobox. The curve-specific controls get loaded in slotCurveName
245 m_cmbCurveName->clear ();
246 m_cmbCurveName->addItem (AXIS_CURVE_NAME);
247 QStringList curveNames = cmdMediator.curvesGraphsNames();
248 QStringList::const_iterator itr;
249 for (itr = curveNames.begin (); itr != curveNames.end (); itr++) {
250
251 QString curveName = *itr;
252 m_cmbCurveName->addItem (curveName);
253 }
254
255 // This sets the curve name
256 m_cmbCurveName->setCurrentText (mainWindow().selectedGraphCurve());
257 loadForCurveName();
258
259 enableOk (false); // Disable Ok button since there not yet any changes
260}
261
262void DlgSettingsColorFilter::loadForCurveName()
263{
264 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::loadForCurveName";
265
266 // Get curve name from control
267 QString curveName = m_cmbCurveName->currentText();
268
269 // Skip if everything is not set up yet
270 if (!curveName.isEmpty () && m_modelColorFilterAfter != nullptr) {
271
272 // Populate controls
273 ColorFilterMode colorFilterMode = m_modelColorFilterAfter->colorFilterMode(curveName);
274 m_btnIntensity->setChecked (colorFilterMode == COLOR_FILTER_MODE_INTENSITY);
275 m_btnForeground->setChecked (colorFilterMode == COLOR_FILTER_MODE_FOREGROUND);
276 m_btnHue->setChecked (colorFilterMode == COLOR_FILTER_MODE_HUE);
277 m_btnSaturation->setChecked (colorFilterMode == COLOR_FILTER_MODE_SATURATION);
278 m_btnValue->setChecked (colorFilterMode == COLOR_FILTER_MODE_VALUE);
279
280 m_scenePreview->clear();
281 m_imagePreview = cmdMediator().document().pixmap().toImage();
282 m_scenePreview->addPixmap (QPixmap::fromImage (m_imagePreview));
283
284 QRgb rgbBackground = createThread ();
285 m_scale->setBackgroundColor (rgbBackground);
286 createThread ();
287 updateHistogram();
288 updatePreview(); // Needs thread initialized
289 }
290}
291
293{
294 if (!smallDialogs) {
295 setMinimumHeight (MINIMUM_HEIGHT);
296 }
297}
298
299void DlgSettingsColorFilter::slotCurveName(const QString & /* curveName */)
300{
301 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::slotCurveName";
302
303 loadForCurveName ();
304}
305
306void DlgSettingsColorFilter::slotDividerHigh (double xCenter)
307{
308 m_modelColorFilterAfter->setHigh (m_cmbCurveName->currentText(),
309 xCenter / double (PROFILE_SCENE_WIDTH ()));
310 updatePreview();
311}
312
313void DlgSettingsColorFilter::slotDividerLow (double xCenter)
314{
315 m_modelColorFilterAfter->setLow (m_cmbCurveName->currentText(),
316 xCenter / double (PROFILE_SCENE_WIDTH ()));
317 updatePreview();
318}
319
320void DlgSettingsColorFilter::slotForeground ()
321{
322 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::slotForeground";
323
324 m_modelColorFilterAfter->setColorFilterMode(m_cmbCurveName->currentText(),
326 updateHistogram();
327 updatePreview();
328}
329
330void DlgSettingsColorFilter::slotHue ()
331{
332 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::slotHue";
333
334 m_modelColorFilterAfter->setColorFilterMode(m_cmbCurveName->currentText(),
336 updateHistogram();
337 updatePreview();
338}
339
340void DlgSettingsColorFilter::slotIntensity ()
341{
342 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::slotIntensity";
343
344 m_modelColorFilterAfter->setColorFilterMode(m_cmbCurveName->currentText(),
346 updateHistogram();
347 updatePreview();
348}
349
350void DlgSettingsColorFilter::slotSaturation ()
351{
352 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::slotSaturation";
353
354 m_modelColorFilterAfter->setColorFilterMode(m_cmbCurveName->currentText(),
356 updateHistogram();
357 updatePreview();
358}
359
361 QImage image)
362{
363 // Overwrite one piece of the processed image. This approach is a bit slow because the entire QPixmap
364 // in the QGraphicsScene gets exchanged as part of each update, but that seems to be the only possible
365 // approach when using QGraphicsScene. If not fast enough or there is ugly flicker, we may replace
366 // QGraphicsScene by a simple QWidget and override the paint function - but that approach may get
367 // complicated when resizing the QGraphicsView
368 for (int xFrom = 0, xTo = xLeft; xFrom < image.width(); xFrom++, xTo++) {
369 for (int y = 0; y < image.height (); y++) {
370
371 QColor pixel = image.pixel (xFrom, y);
372 m_imagePreview.setPixel (xTo, y, pixel.rgb());
373 }
374 }
375
376 // Remove old pixmap
377 QGraphicsItem *itemPixmap = m_scenePreview->items().at(0);
378 m_scenePreview->removeItem (itemPixmap);
379 delete itemPixmap;
380
381 // Save new pixmap. Only visible change should be the area covered by the pixels in image
382 m_scenePreview->addPixmap (QPixmap::fromImage (m_imagePreview));
383}
384
385void DlgSettingsColorFilter::slotValue ()
386{
387 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::slotValue";
388
389 m_modelColorFilterAfter->setColorFilterMode(m_cmbCurveName->currentText(),
391 updateHistogram();
392 updatePreview();
393}
394
395void DlgSettingsColorFilter::updateHistogram()
396{
397 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::updateHistogram";
398
399 enableOk (true);
400
401 const double PEN_WIDTH = 0.0; // Zero value gives one-pixel width at all scales
402
403 QString curveName = m_cmbCurveName->currentText();
404
405 m_sceneProfile->clear();
406
407 m_scale->setColorFilterMode (m_modelColorFilterAfter->colorFilterMode(curveName));
408
409 // Start with original image
410 QImage image = cmdMediator().document().pixmap().toImage();
411
412 double *histogramBins = new double [unsigned (ColorFilterHistogram::HISTOGRAM_BINS ())];
413
414 ColorFilter filter;
415 ColorFilterHistogram filterHistogram;
416 int maxBinCount;
417 filterHistogram.generate (filter,
418 histogramBins,
419 m_modelColorFilterAfter->colorFilterMode (curveName),
420 image,
421 maxBinCount);
422
423 // Draw histogram, normalizing so highest peak exactly fills the vertical range. Log scale is used
424 // so smaller peaks do not disappear
425 double logMaxBinCount = qLn (maxBinCount);
426 if (qAbs (logMaxBinCount) > 0) { // Will not have divide by zero from logMaxBinCount below
427 for (int bin = 1; bin < ColorFilterHistogram::HISTOGRAM_BINS (); bin++) {
428
429 double x0 = PROFILE_SCENE_WIDTH () * (bin - 1.0) / (ColorFilterHistogram::HISTOGRAM_BINS () - 1.0);
430
431 // Map logPixelCount through 0 to 0 through PROFILE_SCENE_HEIGHT-1, using log scale
432 double count0 = 1.0 + histogramBins [bin - 1];
433 double y0 = (PROFILE_SCENE_HEIGHT () - 1.0) * (1.0 - qLn (count0) / logMaxBinCount);
434
435 double x1 = PROFILE_SCENE_WIDTH () * (bin - 0.0) / (ColorFilterHistogram::HISTOGRAM_BINS () - 1.0);
436
437 // Map logPixelCount through 0 to 0 through PROFILE_SCENE_HEIGHT-1, using log scale
438 double count1 = 1.0 + histogramBins [bin];
439 double y1 = (PROFILE_SCENE_HEIGHT () - 1.0) * (1.0 - qLn (count1) / logMaxBinCount);
440
441 QGraphicsLineItem *line = new QGraphicsLineItem (x0, y0, x1, y1);
442 line->setPen (QPen (QBrush (Qt::black), PEN_WIDTH));
443 m_sceneProfile->addItem (line);
444 }
445 }
446
447 // Create low and high dividers
448 m_dividerLow = new ViewProfileDivider(*m_sceneProfile,
449 *m_viewProfile,
450 PROFILE_SCENE_WIDTH (),
451 PROFILE_SCENE_HEIGHT (),
452 qFloor (PROFILE_SCENE_HEIGHT () * 2.0 / 3.0),
453 true);
454 m_dividerHigh = new ViewProfileDivider(*m_sceneProfile,
455 *m_viewProfile,
456 PROFILE_SCENE_HEIGHT (),
457 PROFILE_SCENE_WIDTH (),
458 qFloor (PROFILE_SCENE_HEIGHT () / 3.0),
459 false);
460
461 // Connect the dividers to each other since the shaded areas depend on both divides when low divider is
462 // moved to the right of the high divider
463 connect (m_dividerLow, SIGNAL (signalMovedLow (double)), m_dividerHigh, SLOT (slotOtherMoved(double)));
464 connect (m_dividerHigh, SIGNAL (signalMovedHigh (double)), m_dividerLow, SLOT (slotOtherMoved(double)));
465
466 // Update preview when the dividers move
467 connect (m_dividerLow, SIGNAL (signalMovedLow (double)), this, SLOT (slotDividerLow (double)));
468 connect (m_dividerHigh, SIGNAL(signalMovedHigh (double)), this, SLOT (slotDividerHigh (double)));
469
470 if (m_btnForeground->isChecked()) {
471
472 // Foreground
473 m_dividerLow->setX (m_modelColorFilterAfter->foregroundLow(curveName), FOREGROUND_MIN, FOREGROUND_MAX);
474 m_dividerHigh->setX (m_modelColorFilterAfter->foregroundHigh(curveName), FOREGROUND_MIN, FOREGROUND_MAX);
475
476 } else if (m_btnIntensity->isChecked()) {
477
478 // Intensity
479 m_dividerLow->setX (m_modelColorFilterAfter->intensityLow(curveName), INTENSITY_MIN, INTENSITY_MAX);
480 m_dividerHigh->setX (m_modelColorFilterAfter->intensityHigh(curveName), INTENSITY_MIN, INTENSITY_MAX);
481
482 } else if (m_btnHue->isChecked()) {
483
484 // Hue
485 m_dividerLow->setX (m_modelColorFilterAfter->hueLow(curveName), HUE_MIN, HUE_MAX);
486 m_dividerHigh->setX (m_modelColorFilterAfter->hueHigh(curveName), HUE_MIN, HUE_MAX);
487
488 } else if (m_btnSaturation->isChecked()) {
489
490 // Saturation
491 m_dividerLow->setX (m_modelColorFilterAfter->saturationLow(curveName), SATURATION_MIN, SATURATION_MAX);
492 m_dividerHigh->setX (m_modelColorFilterAfter->saturationHigh(curveName), SATURATION_MIN, SATURATION_MAX);
493
494 } else if (m_btnValue->isChecked()) {
495
496 // Value
497 m_dividerLow->setX (m_modelColorFilterAfter->valueLow(curveName), VALUE_MIN, VALUE_MAX);
498 m_dividerHigh->setX (m_modelColorFilterAfter->valueHigh(curveName), VALUE_MIN, VALUE_MAX);
499
500 } else {
501
502 ENGAUGE_ASSERT (false);
503
504 }
505
506 delete[] histogramBins;
507}
508
509void DlgSettingsColorFilter::updatePreview ()
510{
511 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettings::updatePreview";
512
513 enableOk (true);
514
515 // This (indirectly) updates the preview
516 QString curveName = m_cmbCurveName->currentText();
517 emit signalApplyFilter (m_modelColorFilterAfter->colorFilterMode(curveName),
518 m_modelColorFilterAfter->low(curveName),
519 m_modelColorFilterAfter->high(curveName));
520}
const QString AXIS_CURVE_NAME
const int SATURATION_MAX
const int FOREGROUND_MAX
const int HUE_MAX
const int SATURATION_MIN
const int HUE_MIN
const int INTENSITY_MAX
const int FOREGROUND_MIN
const int VALUE_MAX
const int VALUE_MIN
const int INTENSITY_MIN
Constants for use by CurveFilter and other curve-related classes.
QString colorFilterModeToString(ColorFilterMode colorFilterMode)
ColorFilterMode
@ COLOR_FILTER_MODE_FOREGROUND
@ COLOR_FILTER_MODE_VALUE
@ COLOR_FILTER_MODE_INTENSITY
@ COLOR_FILTER_MODE_SATURATION
@ COLOR_FILTER_MODE_HUE
const int MINIMUM_HEIGHT
const int MINIMUM_DIALOG_WIDTH_COLOR_FILTER
const int MINIMUM_HEIGHT
#define ENGAUGE_ASSERT(cond)
Drop in replacement for Q_ASSERT if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS) define ENGAUGE...
log4cpp::Category * mainCat
Definition Logger.cpp:14
Command queue stack.
Definition CmdMediator.h:24
QStringList curvesGraphsNames() const
See CurvesGraphs::curvesGraphsNames.
Document & document()
Provide the Document to commands, primarily for undo/redo processing.
Command for DlgSettingsColorFilter.
Class that generates a histogram according to the current filter.
void generate(const ColorFilter &filter, double histogramBins[], ColorFilterMode colorFilterMode, const QImage &image, int &maxBinCount) const
Generate the histogram.
static int HISTOGRAM_BINS()
Number of histogram bins.
Class for filtering image to remove unimportant information.
Definition ColorFilter.h:21
QRgb marginColor(const QImage *image) const
Identify the margin color of the image, which is defined as the most common color in the four margins...
Class for processing new filter settings. This is based on http://blog.debao.me/2013/08/how-to-use-qt...
Abstract base class for all Settings dialogs.
void setCmdMediator(CmdMediator &cmdMediator)
Store CmdMediator for easy access by the leaf class.
void finishPanel(QWidget *subPanel, int minimumWidth=MINIMUM_DIALOG_WIDTH, int minimumHeightOrZero=0)
Add Ok and Cancel buttons to subpanel to get the whole dialog.
CmdMediator & cmdMediator()
Provide access to Document information wrapped inside CmdMediator.
void enableOk(bool enable)
Let leaf subclass control the Ok button.
static int MINIMUM_PREVIEW_HEIGHT
Dialog layout constant that guarantees preview has sufficent room.
MainWindow & mainWindow()
Get method for MainWindow.
virtual void load(CmdMediator &cmdMediator)
Load settings from Document.
DlgSettingsColorFilter(MainWindow &mainWindow)
Single constructor.
virtual QWidget * createSubPanel()
Create dialog-specific panel to which base class will add Ok and Cancel buttons.
virtual void createOptionalSaveDefault(QHBoxLayout *layout)
Let subclass define an optional Save As Default button.
virtual void setSmallDialogs(bool smallDialogs)
If false then dialogs have a minimum size so all controls are visible.
void slotTransferPiece(int xLeft, QImage image)
Receive processed piece of preview image, to be inserted at xLeft to xLeft+pixmap....
virtual void handleOk()
Process slotOk.
void signalApplyFilter(ColorFilterMode colorFilterMode, double low, double high)
Send filter parameters to DlgFilterThread and DlgFilterWorker for processing.
Model for DlgSettingsColorFilter and CmdSettingsColorFilter.
double high(const QString &curveName) const
High value of foreground, hue, intensity, saturation or value according to current filter mode.
double low(const QString &curveName) const
Low value of foreground, hue, intensity, saturation or value according to current filter mode normali...
int hueLow(const QString &curveName) const
Get method for hue lower bound.
int hueHigh(const QString &curveName) const
Get method for hue higher bound.
ColorFilterMode colorFilterMode(const QString &curveName) const
Get method for filter mode.
int foregroundHigh(const QString &curveName) const
Get method for foreground higher bound.
int saturationLow(const QString &curveName) const
Get method for saturation lower bound.
int foregroundLow(const QString &curveName) const
Get method for foreground lower bound.
void setHigh(const QString &curveName, double s0To1)
Set the high value for the current filter mode.
int valueLow(const QString &curveName) const
Get method for value low.
int saturationHigh(const QString &curveName) const
Get method for saturation higher bound.
void setColorFilterMode(const QString &curveName, ColorFilterMode colorFilterMode)
Set method for filter mode.
int valueHigh(const QString &curveName) const
Get method for value high.
int intensityHigh(const QString &curveName) const
Get method for intensity higher bound.
void setLow(const QString &curveName, double s0To1)
Set the low value for the current filter mode.
int intensityLow(const QString &curveName) const
Get method for intensity lower bound.
QPixmap pixmap() const
Return the image that is being digitized.
Definition Document.cpp:817
DocumentModelColorFilter modelColorFilter() const
Get method for DocumentModelColorFilter.
Definition Document.cpp:688
Main window consisting of menu, graphics scene, status bar and optional toolbars as a Single Document...
Definition MainWindow.h:92
QString selectedGraphCurve() const
Curve name that is currently selected in m_cmbCurve.
Class that modifies QGraphicsView to automatically expand/shrink the view to fit the window,...
Definition ViewPreview.h:15
@ VIEW_ASPECT_RATIO_VARIABLE
Definition ViewPreview.h:22
Divider that can be dragged, in a dialog QGraphicsView.
void setX(double x, double xLow, double xHigh)
Set the position by specifying the new x coordinate.
Linear horizontal scale, with the spectrum reflecting the active filter parameter.
void setBackgroundColor(QRgb rgbBackground)
Save the background color for foreground calculations.
void setColorFilterMode(ColorFilterMode colorFilterMode)
Change the gradient type.
Class that modifies QGraphicsView to present a two-dimensional profile, with movable dividers for sel...
Definition ViewProfile.h:16
#define LOG4CPP_INFO_S(logger)
Definition convenience.h:18