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