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