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) |
|
||||||||||||
|
Definition at line 103 of file painting.cpp. References Triplet::b, editedImage, findHighestCounts(), Triplet::g, ManipulationOptions::getStatus(), Histogram::highestCountIndex, histogram, StatusWidget::incrementProgress(), newProgress, Triplet::r, resetHistogram(), StatusWidget::showProgressBar(), status, updateIncrement, and Histogram::values. Referenced by EditingInterface::applyEffect(). 00104 {
00105 //load original image
00106 QImage originalImage( filename );
00107
00108 //convert to 32-bit depth if necessary
00109 if( originalImage.depth() < 32 ) { originalImage = originalImage.convertDepth( 32, Qt::AutoColor ); }
00110
00111 //determine if busy indicators will be used
00112 bool useBusyIndicators = false;
00113 StatusWidget* status = NULL;
00114 if( options != NULL && options->getStatus() != NULL )
00115 {
00116 useBusyIndicators = true;
00117 status = options->getStatus();
00118 }
00119
00120 //setup progress bar
00121 if(useBusyIndicators)
00122 {
00123 QString statusMessage = qApp->translate( "oilPaintingEffect", "Applying Oil Painting Effect:" );
00124 status->showProgressBar( statusMessage, 100 );
00125 qApp->processEvents();
00126 }
00127
00128 //update progress bar for every 1% of completion
00129 const int updateIncrement = (int) ( 0.01 * originalImage.width() * originalImage.height() );
00130 int newProgress = 0;
00131
00132 //construct edited image
00133 QImage* editedImage = new QImage( filename );
00134
00135 //convert to 32-bit depth if necessary
00136 if( editedImage->depth() < 32 )
00137 {
00138 QImage* tmp = editedImage;
00139 editedImage = new QImage( tmp->convertDepth( 32, Qt::AutoColor ) );
00140 delete tmp; tmp=NULL;
00141 }
00142
00143 //compute the radius using image resolution
00144 double minDimen = (double) QMIN( editedImage->width(), editedImage->height() );
00145 const int RADIUS = (int) QMAX( 2, (sqrt(minDimen)/4) );
00146
00147 //iterate over image
00148 int originalImageX, originalImageY;
00149 int editedImageX, editedImageY;
00150 int clampedX, clampedY;
00151 int trailingEdgeY, leadingEdgeY;
00152
00153 QRgb* rgb;
00154 uchar* scanLine;
00155 uchar* trailingScanLine;
00156 uchar* leadingScanLine;
00157
00158 //iterate over columns
00159 for( editedImageX=0; editedImageX < editedImage->width(); editedImageX++)
00160 {
00161 //------------------
00162 //reset histogram object
00163 resetHistogram();
00164 //------------------
00165 //fill histogram with data that would have results from Y=-1
00166 for(originalImageY = 0 - 1 - RADIUS;
00167 originalImageY <= 0 - 1 + RADIUS;
00168 originalImageY++)
00169 {
00170 clampedY = QMAX( QMIN( originalImageY, originalImage.height() - 1 ), 0 );
00171 scanLine = originalImage.scanLine( clampedY );
00172
00173 for(originalImageX = editedImageX - RADIUS;
00174 originalImageX <= editedImageX + RADIUS;
00175 originalImageX++)
00176 {
00177 clampedX = QMAX( QMIN( originalImageX, originalImage.width() - 1 ), 0 );
00178
00179 //get rgb value
00180 rgb = ((QRgb*)scanLine+clampedX);
00181
00182 //update counts for this r/g/b value
00183 histogram.values[ qRed(*rgb) ].r++;
00184 histogram.values[ qGreen(*rgb) ].g++;
00185 histogram.values[ qBlue(*rgb) ].b++;
00186 } //originalX
00187 } //originalY
00188 //------------------
00189
00190 //now iterate over rows by simply removing trailing edge data and adding leading edge data
00191 for( editedImageY=0; editedImageY < editedImage->height(); editedImageY++)
00192 {
00193 trailingEdgeY = QMAX( QMIN( editedImageY-1-RADIUS, originalImage.height() - 1 ), 0 );
00194 leadingEdgeY = QMAX( QMIN( editedImageY+RADIUS, originalImage.height() - 1 ), 0 );
00195
00196 trailingScanLine = originalImage.scanLine( trailingEdgeY );
00197 leadingScanLine = originalImage.scanLine( leadingEdgeY );
00198
00199 for(originalImageX = editedImageX - RADIUS;
00200 originalImageX <= editedImageX + RADIUS;
00201 originalImageX++)
00202 {
00203 clampedX = QMAX( QMIN( originalImageX, originalImage.width() - 1 ), 0 );
00204
00205 //remove trail edge data
00206 rgb = ((QRgb*)trailingScanLine+clampedX);
00207 histogram.values[ qRed(*rgb) ].r--;
00208 histogram.values[ qGreen(*rgb) ].g--;
00209 histogram.values[ qBlue(*rgb) ].b--;
00210
00211 //add leading edge data
00212 rgb = ((QRgb*)leadingScanLine+clampedX);
00213 histogram.values[ qRed(*rgb) ].r++;
00214 histogram.values[ qGreen(*rgb) ].g++;
00215 histogram.values[ qBlue(*rgb) ].b++;
00216 } //originalX
00217
00218 //find highest color counts
00219 findHighestCounts();
00220
00221 //replace each color channel value with average of
00222 //current value and most occuring value within neighborhood
00223 scanLine = editedImage->scanLine( editedImageY );
00224 rgb = ((QRgb*)scanLine+editedImageX);
00225 *rgb = qRgb( (qRed(*rgb) + histogram.highestCountIndex.r) / 2,
00226 (qGreen(*rgb) + histogram.highestCountIndex.g) / 2,
00227 (qBlue(*rgb) + histogram.highestCountIndex.b) / 2 );
00228
00229
00230 //update status bar if significant progress has been made since last update
00231 if(useBusyIndicators)
00232 {
00233 newProgress++;
00234 if(newProgress >= updateIncrement)
00235 {
00236 newProgress = 0;
00237 status->incrementProgress();
00238 qApp->processEvents();
00239 }
00240 }
00241
00242 } //editedImageX
00243 } //editedImageY
00244
00245 //return pointer to edited image
00246 return editedImage;
00247 }
|
1.3.9.1