Skip to content

Commit

Permalink
Use QImage method for bilinear resampling
Browse files Browse the repository at this point in the history
  • Loading branch information
mhugent committed Jan 7, 2012
1 parent ea9a2a8 commit 28313b6
Show file tree
Hide file tree
Showing 2 changed files with 1 addition and 105 deletions.
96 changes: 1 addition & 95 deletions src/core/raster/qgsbilinearrasterresampler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,99 +29,5 @@ QgsBilinearRasterResampler::~QgsBilinearRasterResampler()

void QgsBilinearRasterResampler::resample( const QImage& srcImage, QImage& dstImage )
{
double nSrcPerDstX = ( double ) srcImage.width() / ( double ) dstImage.width();
double nSrcPerDstY = ( double ) srcImage.height() / ( double ) dstImage.height();

double currentSrcRow = nSrcPerDstY / 2.0 - 0.5;
double currentSrcCol;
int currentSrcRowInt, currentSrcColInt;
double u, v;

QRgb px1, px2, px3, px4;

for ( int i = 0; i < dstImage.height(); ++i )
{
currentSrcCol = nSrcPerDstX / 2.0 - 0.5;
currentSrcRowInt = floor( currentSrcRow );
v = currentSrcRow - currentSrcRowInt;

for ( int j = 0; j < dstImage.width(); ++j )
{
currentSrcColInt = floor( currentSrcCol );
u = currentSrcCol - currentSrcColInt;

//handle eight edge-cases
if ( currentSrcRowInt < 0 || currentSrcRowInt >= ( srcImage.height() - 1 ) || currentSrcColInt < 0 || currentSrcColInt >= ( srcImage.width() - 1 ) )
{
//pixels at the border of the source image needs to be handled in a special way
if ( currentSrcRowInt < 0 && currentSrcColInt < 0 )
{
dstImage.setPixel( j, i, srcImage.pixel( 0, 0 ) );
}
else if ( currentSrcRowInt < 0 && currentSrcColInt >= ( srcImage.width() - 1 ) )
{
dstImage.setPixel( j, i, srcImage.pixel( srcImage.width() - 1, 0 ) );
}
else if ( currentSrcRowInt >= ( srcImage.height() - 1 ) && currentSrcColInt >= ( srcImage.width() - 1 ) )
{
dstImage.setPixel( j, i, srcImage.pixel( srcImage.width() - 1, srcImage.height() - 1 ) );
}
else if ( currentSrcRowInt >= ( srcImage.height() - 1 ) && currentSrcColInt < 0 )
{
dstImage.setPixel( j, i, srcImage.pixel( 0, srcImage.height() - 1 ) );
}
else if ( currentSrcRowInt < 0 )
{
px1 = srcImage.pixel( currentSrcColInt, 0 );
px2 = srcImage.pixel( currentSrcColInt + 1, 0 );
dstImage.setPixel( j, i, resampleColorValue( u, px1, px2 ) );
}
else if ( currentSrcRowInt >= ( srcImage.height() - 1 ) )
{
px1 = srcImage.pixel( currentSrcColInt, srcImage.height() - 1 );
px2 = srcImage.pixel( currentSrcColInt + 1, srcImage.height() - 1 );
dstImage.setPixel( j, i, resampleColorValue( u, px1, px2 ) );
}
else if ( currentSrcColInt < 0 )
{
px1 = srcImage.pixel( 0, currentSrcRowInt );
px2 = srcImage.pixel( 0, currentSrcRowInt + 1 );
dstImage.setPixel( j, i, resampleColorValue( v, px1, px2 ) );
}
else if ( currentSrcColInt >= ( srcImage.width() - 1 ) )
{
px1 = srcImage.pixel( srcImage.width() - 1, currentSrcRowInt );
px2 = srcImage.pixel( srcImage.width() - 1, currentSrcRowInt + 1 );
dstImage.setPixel( j, i, resampleColorValue( v, px1, px2 ) );
}
currentSrcCol += nSrcPerDstX;
continue;
}

px1 = srcImage.pixel( currentSrcColInt, currentSrcRowInt );
px2 = srcImage.pixel( currentSrcColInt + 1, currentSrcRowInt );
px3 = srcImage.pixel( currentSrcColInt + 1, currentSrcRowInt + 1 );
px4 = srcImage.pixel( currentSrcColInt, currentSrcRowInt + 1 );
dstImage.setPixel( j, i, resampleColorValue( u, v, px1, px2, px3, px4 ) );
currentSrcCol += nSrcPerDstX;
}
currentSrcRow += nSrcPerDstY;
}
}

QRgb QgsBilinearRasterResampler::resampleColorValue( double u, double v, QRgb col1, QRgb col2, QRgb col3, QRgb col4 ) const
{
int red = bilinearInterpolation( u, v, qRed( col1 ), qRed( col2 ), qRed( col3 ), qRed( col4 ) );
int green = bilinearInterpolation( u, v, qGreen( col1 ), qGreen( col2 ), qGreen( col3 ), qGreen( col4 ) );
int blue = bilinearInterpolation( u, v, qBlue( col1 ), qBlue( col2 ), qBlue( col3 ), qBlue( col4 ) );
int alpha = bilinearInterpolation( u, v, qAlpha( col1 ), qAlpha( col2 ), qAlpha( col3 ), qAlpha( col4 ) );
return qRgba( red, green, blue, alpha );
}

QRgb QgsBilinearRasterResampler::resampleColorValue( double u, QRgb col1, QRgb col2 ) const
{
return qRgba( qRed( col1 ) * ( 1 - u ) + qRed( col2 ) * u,
qGreen( col1 ) * ( 1 - u ) + qGreen( col2 ) * u,
qBlue( col1 ) * ( 1 - u ) + qBlue( col2 ) * u,
qAlpha( col1 ) * ( 1 - u ) + qAlpha( col2 ) * u );
dstImage = srcImage.scaled( dstImage.width(), dstImage.height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
}
10 changes: 0 additions & 10 deletions src/core/raster/qgsbilinearrasterresampler.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,6 @@ class QgsBilinearRasterResampler: public QgsRasterResampler

void resample( const QImage& srcImage, QImage& dstImage );
QString type() const { return "bilinear"; }

private:
QRgb resampleColorValue( double u, double v, QRgb col1, QRgb col2, QRgb col3, QRgb col4 ) const;
QRgb resampleColorValue( double u, QRgb col1, QRgb col2 ) const;
inline double bilinearInterpolation( double u, double v, int val1, int val2, int val3, int val4 ) const;
};

double QgsBilinearRasterResampler::bilinearInterpolation( double u, double v, int val1, int val2, int val3, int val4 ) const
{
return ( val1 * ( 1 - u ) * ( 1 - v ) + val2 * ( 1 - v ) * u + val4 * ( 1 - u ) * v + val3 * u * v );
}

#endif // QGSBILINEARRASTERRESAMPLER_H

0 comments on commit 28313b6

Please sign in to comment.