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