Engauge Digitizer  2
DlgFilterWorker.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 "ColorFilter.h"
8 #include "DlgFilterWorker.h"
9 #include "Logger.h"
10 #include <QImage>
11 
12 const int NO_DELAY = 0;
13 const int COLUMNS_PER_PIECE = 5;
14 
15 DlgFilterWorker::DlgFilterWorker(const QPixmap &pixmapOriginal,
16  QRgb rgbBackground) :
17  m_imageOriginal (pixmapOriginal.toImage()),
18  m_rgbBackground (rgbBackground),
19  m_colorFilterMode (NUM_COLOR_FILTER_MODES),
20  m_low (-1.0),
21  m_high (-1.0)
22 {
23  m_restartTimer.setSingleShot (false);
24  connect (&m_restartTimer, SIGNAL (timeout ()), this, SLOT (slotRestartTimeout()));
25 }
26 
27 void DlgFilterWorker::slotNewParameters (ColorFilterMode colorFilterMode,
28  double low,
29  double high)
30 {
31  LOG4CPP_INFO_S ((*mainCat)) << "DlgFilterWorker::slotNewParameters filterMode=" << colorFilterMode
32  << " low=" << low
33  << " high=" << high;
34 
35  // Push onto queue
36  DlgFilterCommand command (colorFilterMode,
37  low,
38  high);
39  m_inputCommandQueue.push_back (command);
40 
41  if (!m_restartTimer.isActive()) {
42 
43  // Timer is not currently active so start it up
44  m_restartTimer.start (NO_DELAY);
45  }
46 }
47 
48 void DlgFilterWorker::slotRestartTimeout ()
49 {
50  if (m_inputCommandQueue.count() > 0) {
51 
52  DlgFilterCommand command = m_inputCommandQueue.last();
53  m_inputCommandQueue.clear ();
54 
55  // Start over from the left side
56  m_colorFilterMode = command.colorFilterMode();
57  m_low = command.low0To1();
58  m_high = command.high0To1();
59 
60  m_xLeft = 0;
61 
62  // Start timer to process first piece
63  m_restartTimer.start (NO_DELAY);
64 
65  } else if (m_xLeft < m_imageOriginal.width ()) {
66 
67  // To to process a new piece, starting at m_xLeft
68  int xStop = m_xLeft + COLUMNS_PER_PIECE;
69  if (xStop >= m_imageOriginal.width()) {
70  xStop = m_imageOriginal.width();
71  }
72 
73  // From here on, if a new command gets pushed onto the queue then we immediately stop processing
74  // and do nothing except start the timer so we can start over after the next timeout. The goal is
75  // to not tie up the gui by emitting signalTransferPiece unnecessarily.
76  //
77  // This code is basically a heavily customized version of ColorFilter::filterImage
78  ColorFilter filter;
79  int processedWidth = xStop - m_xLeft;
80  QImage imageProcessed (processedWidth,
81  m_imageOriginal.height(),
82  QImage::Format_RGB32);
83  for (int xFrom = m_xLeft, xTo = 0; (xFrom < xStop) && (m_inputCommandQueue.count() == 0); xFrom++, xTo++) {
84  for (int y = 0; (y < m_imageOriginal.height ()) && (m_inputCommandQueue.count() == 0); y++) {
85  QColor pixel = m_imageOriginal.pixel (xFrom, y);
86  bool isOn = false;
87  if (pixel.rgb() != m_rgbBackground) {
88 
89  isOn = filter.pixelUnfilteredIsOn (m_colorFilterMode,
90  pixel,
91  m_rgbBackground,
92  m_low,
93  m_high);
94  }
95 
96  imageProcessed.setPixel (xTo, y, (isOn ?
97  QColor (Qt::black).rgb () :
98  QColor (Qt::white).rgb ()));
99  }
100  }
101 
102  if (m_inputCommandQueue.count() == 0) {
103  emit signalTransferPiece (m_xLeft,
104  imageProcessed);
105  m_xLeft += processedWidth;
106  }
107 
108  if ((xStop < m_imageOriginal.width()) ||
109  (m_inputCommandQueue.count () > 0)) {
110 
111  // Restart timer to process next piece
112  m_restartTimer.start (NO_DELAY);
113  }
114  }
115 }
Command pattern object for receiving new parameters in DlgFilterWorker from GUI thread.
double low0To1() const
Get method for low value.
Class for filtering image to remove unimportant information.
Definition: ColorFilter.h:18
void slotNewParameters(ColorFilterMode colorFilterMode, double low, double high)
Start processing with a new set of parameters. Any ongoing processing is interrupted when m_filterMod...
void signalTransferPiece(int xLeft, QImage image)
Send a processed vertical piece of the original pixmap. The destination is between xLeft and xLeft+pi...
double high0To1() const
Get method for high value.
bool pixelUnfilteredIsOn(ColorFilterMode colorFilterMode, const QColor &pixel, QRgb rgbBackground, double low0To1, double high0To1) const
Return true if specified unfiltered pixel is on.
ColorFilterMode colorFilterMode() const
Get method for filter mode.
DlgFilterWorker(const QPixmap &pixmapOriginal, QRgb m_rgbBackground)
Single constructor.