Engauge Digitizer  2
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"
10 #include "ColorFilterHistogram.h"
11 #include "ColorConstants.h"
12 #include "DlgFilterThread.h"
13 #include "DlgSettingsColorFilter.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 
34 const 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 
60 void 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 
116 void DlgSettingsColorFilter::createOptionalSaveDefault (QHBoxLayout * /* layout */)
117 {
118 }
119 
120 void 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 
140 void 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 
196 QRgb 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 
262 void 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 
299 void DlgSettingsColorFilter::slotCurveName(const QString & /* curveName */)
300 {
301  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::slotCurveName";
302 
303  loadForCurveName ();
304 }
305 
306 void DlgSettingsColorFilter::slotDividerHigh (double xCenter)
307 {
308  m_modelColorFilterAfter->setHigh (m_cmbCurveName->currentText(),
309  xCenter / double (PROFILE_SCENE_WIDTH ()));
310  updatePreview();
311 }
312 
313 void DlgSettingsColorFilter::slotDividerLow (double xCenter)
314 {
315  m_modelColorFilterAfter->setLow (m_cmbCurveName->currentText(),
316  xCenter / double (PROFILE_SCENE_WIDTH ()));
317  updatePreview();
318 }
319 
320 void DlgSettingsColorFilter::slotForeground ()
321 {
322  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::slotForeground";
323 
324  m_modelColorFilterAfter->setColorFilterMode(m_cmbCurveName->currentText(),
326  updateHistogram();
327  updatePreview();
328 }
329 
330 void DlgSettingsColorFilter::slotHue ()
331 {
332  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::slotHue";
333 
334  m_modelColorFilterAfter->setColorFilterMode(m_cmbCurveName->currentText(),
336  updateHistogram();
337  updatePreview();
338 }
339 
340 void DlgSettingsColorFilter::slotIntensity ()
341 {
342  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::slotIntensity";
343 
344  m_modelColorFilterAfter->setColorFilterMode(m_cmbCurveName->currentText(),
346  updateHistogram();
347  updatePreview();
348 }
349 
350 void 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 
385 void DlgSettingsColorFilter::slotValue ()
386 {
387  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::slotValue";
388 
389  m_modelColorFilterAfter->setColorFilterMode(m_cmbCurveName->currentText(),
391  updateHistogram();
392  updatePreview();
393 }
394 
395 void 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 
509 void 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 }
void setBackgroundColor(QRgb rgbBackground)
Save the background color for foreground calculations.
const int SATURATION_MIN
int intensityHigh(const QString &curveName) const
Get method for intensity higher bound.
int valueHigh(const QString &curveName) const
Get method for value high.
const int VALUE_MAX
const int MINIMUM_HEIGHT
int valueLow(const QString &curveName) const
Get method for value low.
void setColorFilterMode(const QString &curveName, ColorFilterMode colorFilterMode)
Set method for filter mode.
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...
Definition: ColorFilter.cpp:78
const int VALUE_MIN
int hueHigh(const QString &curveName) const
Get method for hue higher bound.
const int HUE_MAX
const int FOREGROUND_MIN
void setX(double x, double xLow, double xHigh)
Set the position by specifying the new x coordinate.
int saturationLow(const QString &curveName) const
Get method for saturation lower bound.
int foregroundHigh(const QString &curveName) const
Get method for foreground higher bound.
void setCmdMediator(CmdMediator &cmdMediator)
Store CmdMediator for easy access by the leaf class.
const int SATURATION_MAX
DocumentModelColorFilter modelColorFilter() const
Get method for DocumentModelColorFilter.
Definition: Document.cpp:688
#define LOG4CPP_INFO_S(logger)
Definition: convenience.h:18
const int HUE_MIN
Document & document()
Provide the Document to commands, primarily for undo/redo processing.
Definition: CmdMediator.cpp:72
Class for filtering image to remove unimportant information.
Definition: ColorFilter.h:20
QString colorFilterModeToString(ColorFilterMode colorFilterMode)
void slotTransferPiece(int xLeft, QImage image)
Receive processed piece of preview image, to be inserted at xLeft to xLeft+pixmap....
ColorFilterMode colorFilterMode(const QString &curveName) const
Get method for filter mode.
int hueLow(const QString &curveName) const
Get method for hue lower bound.
void finishPanel(QWidget *subPanel, int minimumWidth=MINIMUM_DIALOG_WIDTH, int minimumHeightOrZero=0)
Add Ok and Cancel buttons to subpanel to get the whole dialog.
virtual void handleOk()
Process slotOk.
int saturationHigh(const QString &curveName) const
Get method for saturation higher bound.
void generate(const ColorFilter &filter, double histogramBins [], ColorFilterMode colorFilterMode, const QImage &image, int &maxBinCount) const
Generate the histogram.
double high(const QString &curveName) const
High value of foreground, hue, intensity, saturation or value according to current filter mode.
void signalApplyFilter(ColorFilterMode colorFilterMode, double low, double high)
Send filter parameters to DlgFilterThread and DlgFilterWorker for processing.
ColorFilterMode
virtual void setSmallDialogs(bool smallDialogs)
If false then dialogs have a minimum size so all controls are visible.
virtual void load(CmdMediator &cmdMediator)
Load settings from Document.
int intensityLow(const QString &curveName) const
Get method for intensity lower bound.
const int MINIMUM_DIALOG_WIDTH_COLOR_FILTER
void setHigh(const QString &curveName, double s0To1)
Set the high value for the current filter mode.
Class that modifies QGraphicsView to automatically expand/shrink the view to fit the window,...
Definition: ViewPreview.h:14
const int INTENSITY_MIN
Constants for use by CurveFilter and other curve-related classes.
Model for DlgSettingsColorFilter and CmdSettingsColorFilter.
Linear horizontal scale, with the spectrum reflecting the active filter parameter.
void setColorFilterMode(ColorFilterMode colorFilterMode)
Change the gradient type.
Divider that can be dragged, in a dialog QGraphicsView.
Class for processing new filter settings. This is based on http://blog.debao.me/2013/08/how-to-use-qt...
int foregroundLow(const QString &curveName) const
Get method for foreground lower bound.
void setLow(const QString &curveName, double s0To1)
Set the low value for the current filter mode.
Command for DlgSettingsColorFilter.
virtual void createOptionalSaveDefault(QHBoxLayout *layout)
Let subclass define an optional Save As Default button.
virtual QWidget * createSubPanel()
Create dialog-specific panel to which base class will add Ok and Cancel buttons.
log4cpp::Category * mainCat
Definition: Logger.cpp:14
static int MINIMUM_PREVIEW_HEIGHT
Dialog layout constant that guarantees preview has sufficent room.
void enableOk(bool enable)
Let leaf subclass control the Ok button.
const int FOREGROUND_MAX
Command queue stack.
Definition: CmdMediator.h:23
DlgSettingsColorFilter(MainWindow &mainWindow)
Single constructor.
Abstract base class for all Settings dialogs.
QPixmap pixmap() const
Return the image that is being digitized.
Definition: Document.cpp:817
Class that generates a histogram according to the current filter.
Class that modifies QGraphicsView to present a two-dimensional profile, with movable dividers for sel...
Definition: ViewProfile.h:15
double low(const QString &curveName) const
Low value of foreground, hue, intensity, saturation or value according to current filter mode normali...
static int HISTOGRAM_BINS()
Number of histogram bins.
MainWindow & mainWindow()
Get method for MainWindow.
const int INTENSITY_MAX
Main window consisting of menu, graphics scene, status bar and optional toolbars as a Single Document...
Definition: MainWindow.h:91
QStringList curvesGraphsNames() const
See CurvesGraphs::curvesGraphsNames.
Definition: CmdMediator.cpp:62
CmdMediator & cmdMediator()
Provide access to Document information wrapped inside CmdMediator.
const QString AXIS_CURVE_NAME
#define ENGAUGE_ASSERT(cond)
Drop in replacement for Q_ASSERT if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS) define ENGAUGE...
Definition: EngaugeAssert.h:20