AlbumShaper  1.0a3
Functions
painting.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

QImage * oilPaintingEffect (QString filename, ManipulationOptions *options)
 

Function Documentation

§ oilPaintingEffect()

QImage* oilPaintingEffect ( QString  filename,
ManipulationOptions options 
)

Definition at line 106 of file painting.cpp.

References Triplet::b, editedImage, findHighestCounts(), Triplet::g, ManipulationOptions::getStatus(), Histogram::highestCountIndex, StatusWidget::incrementProgress(), MAX, MIN, newProgress, Triplet::r, resetHistogram(), StatusWidget::showProgressBar(), status, updateIncrement, and Histogram::values.

Referenced by EditingInterface::applyEffect().

107 {
108  //load original image
109  QImage originalImage( filename );
110 
111  //convert to 32-bit depth if necessary
112  if( originalImage.depth() < 32 ) { originalImage = originalImage.convertDepth( 32, Qt::AutoColor ); }
113 
114 //determine if busy indicators will be used
115  bool useBusyIndicators = false;
116  StatusWidget* status = NULL;
117  if( options != NULL && options->getStatus() != NULL )
118  {
119  useBusyIndicators = true;
120  status = options->getStatus();
121  }
122 
123  //setup progress bar
124  if(useBusyIndicators)
125  {
126  QString statusMessage = qApp->translate( "oilPaintingEffect", "Applying Oil Painting Effect:" );
127  status->showProgressBar( statusMessage, 100 );
128  qApp->processEvents();
129  }
130 
131  //update progress bar for every 1% of completion
132  const int updateIncrement = (int) ( 0.01 * originalImage.width() * originalImage.height() );
133  int newProgress = 0;
134 
135  //construct edited image
136  QImage* editedImage = new QImage( filename );
137 
138  //convert to 32-bit depth if necessary
139  if( editedImage->depth() < 32 )
140  {
141  QImage* tmp = editedImage;
142  editedImage = new QImage( tmp->convertDepth( 32, Qt::AutoColor ) );
143  delete tmp; tmp=NULL;
144  }
145 
146  //compute the radius using image resolution
147  double minDimen = (double) MIN( editedImage->width(), editedImage->height() );
148  const int RADIUS = (int) MAX( 2, (sqrt(minDimen)/4) );
149 
150  //iterate over image
151  int originalImageX, originalImageY;
152  int editedImageX, editedImageY;
153  int clampedX, clampedY;
154  int trailingEdgeY, leadingEdgeY;
155 
156  QRgb* rgb;
157  uchar* scanLine;
158  uchar* trailingScanLine;
159  uchar* leadingScanLine;
160 
161  //iterate over columns
162  for( editedImageX=0; editedImageX < editedImage->width(); editedImageX++)
163  {
164  //------------------
165  //reset histogram object
166  resetHistogram();
167  //------------------
168  //fill histogram with data that would have results from Y=-1
169  for(originalImageY = 0 - 1 - RADIUS;
170  originalImageY <= 0 - 1 + RADIUS;
171  originalImageY++)
172  {
173  clampedY = MAX( MIN( originalImageY, originalImage.height() - 1 ), 0 );
174  scanLine = originalImage.scanLine( clampedY );
175 
176  for(originalImageX = editedImageX - RADIUS;
177  originalImageX <= editedImageX + RADIUS;
178  originalImageX++)
179  {
180  clampedX = MAX( MIN( originalImageX, originalImage.width() - 1 ), 0 );
181 
182  //get rgb value
183  rgb = ((QRgb*)scanLine+clampedX);
184 
185  //update counts for this r/g/b value
186  histogram.values[ qRed(*rgb) ].r++;
187  histogram.values[ qGreen(*rgb) ].g++;
188  histogram.values[ qBlue(*rgb) ].b++;
189  } //originalX
190  } //originalY
191  //------------------
192 
193  //now iterate over rows by simply removing trailing edge data and adding leading edge data
194  for( editedImageY=0; editedImageY < editedImage->height(); editedImageY++)
195  {
196  trailingEdgeY = MAX( MIN( editedImageY-1-RADIUS, originalImage.height() - 1 ), 0 );
197  leadingEdgeY = MAX( MIN( editedImageY+RADIUS, originalImage.height() - 1 ), 0 );
198 
199  trailingScanLine = originalImage.scanLine( trailingEdgeY );
200  leadingScanLine = originalImage.scanLine( leadingEdgeY );
201 
202  for(originalImageX = editedImageX - RADIUS;
203  originalImageX <= editedImageX + RADIUS;
204  originalImageX++)
205  {
206  clampedX = MAX( MIN( originalImageX, originalImage.width() - 1 ), 0 );
207 
208  //remove trail edge data
209  rgb = ((QRgb*)trailingScanLine+clampedX);
210  histogram.values[ qRed(*rgb) ].r--;
211  histogram.values[ qGreen(*rgb) ].g--;
212  histogram.values[ qBlue(*rgb) ].b--;
213 
214  //add leading edge data
215  rgb = ((QRgb*)leadingScanLine+clampedX);
216  histogram.values[ qRed(*rgb) ].r++;
217  histogram.values[ qGreen(*rgb) ].g++;
218  histogram.values[ qBlue(*rgb) ].b++;
219  } //originalX
220 
221  //find highest color counts
223 
224  //replace each color channel value with average of
225  //current value and most occuring value within neighborhood
226  scanLine = editedImage->scanLine( editedImageY );
227  rgb = ((QRgb*)scanLine+editedImageX);
228  *rgb = qRgb( (qRed(*rgb) + histogram.highestCountIndex.r) / 2,
229  (qGreen(*rgb) + histogram.highestCountIndex.g) / 2,
230  (qBlue(*rgb) + histogram.highestCountIndex.b) / 2 );
231 
232 
233  //update status bar if significant progress has been made since last update
234  if(useBusyIndicators)
235  {
236  newProgress++;
237  if(newProgress >= updateIncrement)
238  {
239  newProgress = 0;
240  status->incrementProgress();
241  qApp->processEvents();
242  }
243  }
244 
245  } //editedImageX
246  } //editedImageY
247 
248  //return pointer to edited image
249  return editedImage;
250 }
int updateIncrement
#define MAX(x, y)
Definition: painting.cpp:18
Triplet values[256]
Definition: painting.cpp:68
StatusWidget * getStatus()
void incrementProgress()
Updates the progress bar by one step.
void showProgressBar(QString message, int numSteps)
Initializes the progress bar.
void findHighestCounts()
Definition: painting.cpp:90
int b
Definition: painting.cpp:63
Triplet highestCountIndex
Definition: painting.cpp:71
int g
Definition: painting.cpp:63
int r
Definition: painting.cpp:63
StatusWidget * status
void resetHistogram()
Definition: painting.cpp:76
Histogram histogram
Definition: painting.cpp:74
#define MIN(x, y)
Definition: painting.cpp:17
QImage * editedImage
int newProgress