From 77fee0796823763923593d1f0d2fdd1e5039bc5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Tue, 22 Jan 2013 12:10:52 +0100 Subject: [PATCH] A?adida nueva implementaci?n de filtros m?s eficiente. --- YACReader/render.cpp | 146 +++++++++++++++++++++++++++++++++++++++++-- YACReader/render.h | 10 ++- 2 files changed, 149 insertions(+), 7 deletions(-) diff --git a/YACReader/render.cpp b/YACReader/render.cpp index d1429266..4e2ca521 100644 --- a/YACReader/render.cpp +++ b/YACReader/render.cpp @@ -10,6 +10,124 @@ #define NL 2 #define NR 2 +template +inline const T& kClamp( const T& x, const T& low, const T& high ) +{ + if ( x < low ) return low; + else if ( high < x ) return high; + else return x; +} + +inline +int changeBrightness( int value, int brightness ) + { + return kClamp( value + brightness * 255 / 100, 0, 255 ); + } + +inline +int changeContrast( int value, int contrast ) + { + return kClamp((( value - 127 ) * contrast / 100 ) + 127, 0, 255 ); + } + +inline +int changeGamma( int value, int gamma ) + { + return kClamp( int( pow( value / 255.0, 100.0 / gamma ) * 255 ), 0, 255 ); + } + +inline +int changeUsingTable( int value, const int table[] ) + { + return table[ value ]; + } + +template< int operation( int, int ) > +static +QImage changeImage( const QImage& image, int value ) + { + QImage im = image; + im.detach(); + if( im.numColors() == 0 ) /* truecolor */ + { + if( im.format() != QImage::Format_RGB32 ) /* just in case */ + im = im.convertToFormat( QImage::Format_RGB32 ); + int table[ 256 ]; + for( int i = 0; + i < 256; + ++i ) + table[ i ] = operation( i, value ); + if( im.hasAlphaChannel() ) + { + for( int y = 0; + y < im.height(); + ++y ) + { + QRgb* line = reinterpret_cast< QRgb* >( im.scanLine( y )); + for( int x = 0; + x < im.width(); + ++x ) + line[ x ] = qRgba( changeUsingTable( qRed( line[ x ] ), table ), + changeUsingTable( qGreen( line[ x ] ), table ), + changeUsingTable( qBlue( line[ x ] ), table ), + changeUsingTable( qAlpha( line[ x ] ), table )); + } + } + else + { + for( int y = 0; + y < im.height(); + ++y ) + { + QRgb* line = reinterpret_cast< QRgb* >( im.scanLine( y )); + for( int x = 0; + x < im.width(); + ++x ) + line[ x ] = qRgb( changeUsingTable( qRed( line[ x ] ), table ), + changeUsingTable( qGreen( line[ x ] ), table ), + changeUsingTable( qBlue( line[ x ] ), table )); + } + } + } + else + { + QVector colors = im.colorTable(); + for( int i = 0; + i < im.numColors(); + ++i ) + colors[ i ] = qRgb( operation( qRed( colors[ i ] ), value ), + operation( qGreen( colors[ i ] ), value ), + operation( qBlue( colors[ i ] ), value )); + } + return im; + } + + +// brightness is multiplied by 100 in order to avoid floating point numbers +QImage changeBrightness( const QImage& image, int brightness ) + { + if( brightness == 0 ) // no change + return image; + return changeImage< changeBrightness >( image, brightness ); + } + + +// contrast is multiplied by 100 in order to avoid floating point numbers +QImage changeContrast( const QImage& image, int contrast ) + { + if( contrast == 100 ) // no change + return image; + return changeImage< changeContrast >( image, contrast ); + } + +// gamma is multiplied by 100 in order to avoid floating point numbers +QImage changeGamma( const QImage& image, int gamma ) + { + if( gamma == 100 ) // no change + return image; + return changeImage< changeGamma >( image, gamma ); + } + QMutex mutex; //----------------------------------------------------------------------------- @@ -110,7 +228,7 @@ BrightnessFilter::BrightnessFilter(int l) QImage BrightnessFilter::setFilter(const QImage & image) { - int width = image.width(); + /*int width = image.width(); int height = image.height(); QImage result(width,height,image.format()); @@ -119,20 +237,23 @@ QImage BrightnessFilter::setFilter(const QImage & image) result.setPixel(i,j,QColor(image.pixel(i,j)).light(level).rgb()); } } - return result; + return result;*/ + + return changeBrightness(image,50); } //----------------------------------------------------------------------------- // ContrastFilter //----------------------------------------------------------------------------- -ContrastFilter::ContrastFilter() +ContrastFilter::ContrastFilter(int l) + :level(l) { } QImage ContrastFilter::setFilter(const QImage & image) { - int width = image.width(); + /*int width = image.width(); int height = image.height(); QImage result(width,height,image.format()); @@ -187,9 +308,22 @@ QImage ContrastFilter::setFilter(const QImage & image) } } - return result; + return result;*/ + + return changeContrast(image,level); +} +//----------------------------------------------------------------------------- +// ContrastFilter +//----------------------------------------------------------------------------- +GammaFilter::GammaFilter(int l) + :level(l) +{ } +QImage GammaFilter::setFilter(const QImage & image) +{ + return changeGamma(image,level); +} //----------------------------------------------------------------------------- // PageRender @@ -304,7 +438,7 @@ Render::Render() pageRenders.push_back(0); } - //filters.push_back(new ContrastFilter()); + //filters.push_back(new GammaFilter(250)); } //Este método se encarga de forzar el renderizado de las páginas. diff --git a/YACReader/render.h b/YACReader/render.h index 135e1ba6..cab7d1eb 100644 --- a/YACReader/render.h +++ b/YACReader/render.h @@ -50,7 +50,15 @@ private: class ContrastFilter : public ImageFilter { public: - ContrastFilter(); + ContrastFilter(int l=150); + virtual QImage setFilter(const QImage & image); +private: + int level; +}; + +class GammaFilter : public ImageFilter { +public: + GammaFilter(int l=150); virtual QImage setFilter(const QImage & image); private: int level;