|
AlbumShaper
1.0a3
|
#include <qimage.h>#include <qstring.h>#include <qapplication.h>#include <math.h>#include "painting.h"#include "manipulationOptions.h"#include "../../gui/statusWidget.h"
Go to the source code of this file.
Classes | |
| struct | Triplet |
| struct | Histogram |
Functions | |
| void | resetHistogram () |
| void | findHighestCounts () |
| QImage * | oilPaintingEffect (QString filename, ManipulationOptions *options) |
Variables | |
| Histogram | histogram |
| void findHighestCounts | ( | ) |
Definition at line 87 of file painting.cpp.
References Triplet::b, Triplet::g, Histogram::highestCountIndex, Triplet::r, and Histogram::values.
Referenced by oilPaintingEffect().
{
static int i;
for(i = 1; i<256; i++)
{
if( histogram.values[i].r > histogram.values[ histogram.highestCountIndex.r ].r )
{ histogram.highestCountIndex.r = i; }
if( histogram.values[i].g > histogram.values[ histogram.highestCountIndex.g ].g )
{ histogram.highestCountIndex.g = i; }
if( histogram.values[i].b > histogram.values[ histogram.highestCountIndex.b ].b )
{ histogram.highestCountIndex.b = i; }
}
}
| 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, StatusWidget::incrementProgress(), newProgress, Triplet::r, resetHistogram(), StatusWidget::showProgressBar(), status, updateIncrement, and Histogram::values.
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 ); }
//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( "oilPaintingEffect", "Applying Oil Painting 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;
//construct 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;
}
//compute the radius using image resolution
double minDimen = (double) QMIN( editedImage->width(), editedImage->height() );
const int RADIUS = (int) QMAX( 2, (sqrt(minDimen)/4) );
//iterate over image
int originalImageX, originalImageY;
int editedImageX, editedImageY;
int clampedX, clampedY;
int trailingEdgeY, leadingEdgeY;
QRgb* rgb;
uchar* scanLine;
uchar* trailingScanLine;
uchar* leadingScanLine;
//iterate over columns
for( editedImageX=0; editedImageX < editedImage->width(); editedImageX++)
{
//------------------
//reset histogram object
resetHistogram();
//------------------
//fill histogram with data that would have results from Y=-1
for(originalImageY = 0 - 1 - RADIUS;
originalImageY <= 0 - 1 + RADIUS;
originalImageY++)
{
clampedY = QMAX( QMIN( originalImageY, originalImage.height() - 1 ), 0 );
scanLine = originalImage.scanLine( clampedY );
for(originalImageX = editedImageX - RADIUS;
originalImageX <= editedImageX + RADIUS;
originalImageX++)
{
clampedX = QMAX( QMIN( originalImageX, originalImage.width() - 1 ), 0 );
//get rgb value
rgb = ((QRgb*)scanLine+clampedX);
//update counts for this r/g/b value
histogram.values[ qRed(*rgb) ].r++;
histogram.values[ qGreen(*rgb) ].g++;
histogram.values[ qBlue(*rgb) ].b++;
} //originalX
} //originalY
//------------------
//now iterate over rows by simply removing trailing edge data and adding leading edge data
for( editedImageY=0; editedImageY < editedImage->height(); editedImageY++)
{
trailingEdgeY = QMAX( QMIN( editedImageY-1-RADIUS, originalImage.height() - 1 ), 0 );
leadingEdgeY = QMAX( QMIN( editedImageY+RADIUS, originalImage.height() - 1 ), 0 );
trailingScanLine = originalImage.scanLine( trailingEdgeY );
leadingScanLine = originalImage.scanLine( leadingEdgeY );
for(originalImageX = editedImageX - RADIUS;
originalImageX <= editedImageX + RADIUS;
originalImageX++)
{
clampedX = QMAX( QMIN( originalImageX, originalImage.width() - 1 ), 0 );
//remove trail edge data
rgb = ((QRgb*)trailingScanLine+clampedX);
histogram.values[ qRed(*rgb) ].r--;
histogram.values[ qGreen(*rgb) ].g--;
histogram.values[ qBlue(*rgb) ].b--;
//add leading edge data
rgb = ((QRgb*)leadingScanLine+clampedX);
histogram.values[ qRed(*rgb) ].r++;
histogram.values[ qGreen(*rgb) ].g++;
histogram.values[ qBlue(*rgb) ].b++;
} //originalX
//find highest color counts
findHighestCounts();
//replace each color channel value with average of
//current value and most occuring value within neighborhood
scanLine = editedImage->scanLine( editedImageY );
rgb = ((QRgb*)scanLine+editedImageX);
*rgb = qRgb( (qRed(*rgb) + histogram.highestCountIndex.r) / 2,
(qGreen(*rgb) + histogram.highestCountIndex.g) / 2,
(qBlue(*rgb) + histogram.highestCountIndex.b) / 2 );
//update status bar if significant progress has been made since last update
if(useBusyIndicators)
{
newProgress++;
if(newProgress >= updateIncrement)
{
newProgress = 0;
status->incrementProgress();
qApp->processEvents();
}
}
} //editedImageX
} //editedImageY
//return pointer to edited image
return editedImage;
}
| void resetHistogram | ( | ) |
Definition at line 73 of file painting.cpp.
References Triplet::b, Triplet::g, Histogram::highestCountIndex, Triplet::r, and Histogram::values.
Referenced by oilPaintingEffect().
Definition at line 71 of file painting.cpp.
1.7.5.1