AlbumShaper
1.0a3
|
Go to the source code of this file.
Functions | |
QImage * | embossEffect (QString filename, ManipulationOptions *options) |
QImage* embossEffect | ( | QString | filename, |
ManipulationOptions * | options | ||
) |
Definition at line 82 of file emboss.cpp.
References b, editedImage, ManipulationOptions::getStatus(), HSVtoRGB(), StatusWidget::incrementProgress(), newProgress, RGBtoHSV(), StatusWidget::showProgressBar(), status, and updateIncrement.
Referenced by EditingInterface::applyEffect().
{ //load original image QImage originalImage( filename ); //convert to 32-bit depth if necessary if( originalImage.depth() < 32 ) { originalImage = originalImage.convertDepth( 32, Qt::AutoColor ); } //create edited image QImage* editedImage = new QImage( filename ); //convert to 32-bit depth if necessary if( editedImage->depth() < 32 ) { QImage* tmp = editedImage; editedImage = new QImage( tmp->convertDepth( 32, Qt::AutoColor ) ); delete tmp; tmp=NULL; } //determine if busy indicators will be used bool useBusyIndicators = false; StatusWidget* status = NULL; if( options != NULL && options->getStatus() != NULL ) { useBusyIndicators = true; status = options->getStatus(); } //setup progress bar if(useBusyIndicators) { QString statusMessage = qApp->translate( "embossEffect", "Applying Emboss Effect:" ); status->showProgressBar( statusMessage, 100 ); qApp->processEvents(); } //update progress bar for every 1% of completion const int updateIncrement = (int) ( 0.01 * originalImage.width() * originalImage.height() ); int newProgress = 0; //iterate over each selected scanline int x, y; QRgb* rgb; uchar* scanLine; int yPrev, yNext, xPrev, xNext; //compute the radius using image resolution double minDimen = (double) QMIN( editedImage->width(), editedImage->height() ); const int embossRadius = (int) QMAX( 1, (sqrt(minDimen)/8) ); for( y=0; y<editedImage->height(); y++) { scanLine = originalImage.scanLine(y); //compute previous and next y pixel coordinates yPrev = QMAX( y-embossRadius, 0 ); yNext = QMIN( y+embossRadius, editedImage->height() - 1 ); //iterate over each selected pixel in scanline for( x=0; x<editedImage->width(); x++) { //compute previous and next x pixel coordinates xPrev = QMAX( x-embossRadius, 0 ); xNext = QMIN( x+embossRadius, editedImage->width() - 1 ); //start with a default luminance of 128 (50% luminance) int sum = 128; //sum weighted gray values of neighbors scanLine = originalImage.scanLine( yPrev ); sum-= qGray( *((QRgb*)scanLine + xPrev ) ); sum-= qGray( *((QRgb*)scanLine + x ) ); scanLine = originalImage.scanLine( y ); sum-= qGray( *((QRgb*)scanLine + xPrev ) ); sum+= qGray( *((QRgb*)scanLine + xNext ) ); scanLine = originalImage.scanLine( yNext ); sum+= qGray( *((QRgb*)scanLine + x ) ); sum+= qGray( *((QRgb*)scanLine + xNext ) ); //clamp sum to within 0-255 range sum = QMAX( QMIN( sum, 255), 0 ); //get original pixel color in HSV space scanLine = editedImage->scanLine(y); rgb = ((QRgb*)scanLine+x); double r = ((double)qRed(*rgb) )/255.0; double g = ((double)qGreen(*rgb) )/255.0; double b = ((double)qBlue(*rgb) )/255.0; //convert to hsv double h,s,v; RGBtoHSV(r,g,b,&h,&s,&v); //reset v v = ((double)sum)/255; //convert adjusted color back to rgb colorspace and clamp HSVtoRGB( &r,&g,&b, h,s,v); int rp = (int) QMIN( QMAX((r*255), 0), 255 ); int gp = (int) QMIN( QMAX((g*255), 0), 255 ); int bp = (int) QMIN( QMAX((b*255), 0), 255 ); //set adjusted color value *rgb = qRgb(rp,gp,bp); //update status bar if significant progress has been made since last update if(useBusyIndicators) { newProgress++; if(newProgress >= updateIncrement) { newProgress = 0; status->incrementProgress(); qApp->processEvents(); } } } } //return pointer to edited image return editedImage; }