Skip to content

Commit

Permalink
Consider transparency in raster renderer
Browse files Browse the repository at this point in the history
  • Loading branch information
mhugent committed Dec 27, 2011
1 parent 25f8ec5 commit 76cc219
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 6 deletions.
52 changes: 49 additions & 3 deletions src/core/raster/qgspalettedrasterrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "qgscoordinatetransform.h"
#include "qgsmaptopixel.h"
#include "qgsrasterresampler.h"
#include "qgsrastertransparency.h"
#include "qgsrasterviewport.h"
#include <QColor>
#include <QImage>
Expand All @@ -43,18 +44,42 @@ void QgsPalettedRasterRenderer::draw( QPainter* p, QgsRasterViewPort* viewPort,
}

double oversampling;
QgsRasterDataProvider::DataType transparencyType;
if ( mAlphaBand > 0 )
{
transparencyType = ( QgsRasterDataProvider::DataType )mProvider->dataType( mAlphaBand );
}
startRasterRead( mBandNumber, viewPort, theQgsMapToPixel, oversampling );

//Read alpha band if necessary
if ( mAlphaBand > 0 && mAlphaBand != mBandNumber )
{
startRasterRead( mAlphaBand, viewPort, theQgsMapToPixel, oversampling );
}

int nCols = 0;
int nRows = 0;
int topLeftCol = 0;
int topLeftRow = 0;
int currentRasterPos = 0;
QgsRasterDataProvider::DataType rasterType = ( QgsRasterDataProvider::DataType )mProvider->dataType( mBandNumber );
void* rasterData;
double currentOpacity = mOpacity;

bool hasTransparency = usesTransparency();
void* transparencyData;

while ( readNextRasterPart( mBandNumber, viewPort, nCols, nRows, &rasterData, topLeftCol, topLeftRow ) )
{
if ( mAlphaBand > 0 && mAlphaBand != mBandNumber )
{
readNextRasterPart( mAlphaBand, viewPort, nCols, nRows, &transparencyData, topLeftCol, topLeftRow );
}
else if ( mAlphaBand == mBandNumber )
{
transparencyData = rasterData;
}

//create image
QImage img( nCols, nRows, QImage::Format_ARGB32_Premultiplied );
QRgb* imageScanLine = 0;
Expand All @@ -67,9 +92,24 @@ void QgsPalettedRasterRenderer::draw( QPainter* p, QgsRasterViewPort* viewPort,
for ( int j = 0; j < nCols; ++j )
{
val = readValue( rasterData, rasterType, currentRasterPos );
//imageScanLine[j] = mColors[ val ].rgba();
QColor& currentColor = mColors[val];
imageScanLine[j] = qRgba( mOpacity * currentColor.red(), mOpacity * currentColor.green(), mOpacity * currentColor.blue(), mOpacity * 255 );
if ( !hasTransparency )
{
imageScanLine[j] = mColors[ val ].rgba();
}
else
{
currentOpacity = mOpacity;
if ( mRasterTransparency )
{
currentOpacity = mRasterTransparency->alphaValue( val, mOpacity * 255 ) / 255.0;
}
if ( mAlphaBand >= 0 )
{
currentOpacity *= ( readValue( transparencyData, transparencyType, currentRasterPos ) / 255.0 );
}
QColor& currentColor = mColors[val];
imageScanLine[j] = qRgba( currentOpacity * currentColor.red(), currentOpacity * currentColor.green(), currentOpacity * currentColor.blue(), currentOpacity * 255 );
}
++currentRasterPos;
}
}
Expand All @@ -90,5 +130,11 @@ void QgsPalettedRasterRenderer::draw( QPainter* p, QgsRasterViewPort* viewPort,
p->drawImage( tlPoint, img );
}
}

//stop raster reading
stopRasterRead( mBandNumber );
if ( mAlphaBand > 0 && mAlphaBand != mBandNumber )
{
stopRasterRead( mAlphaBand );
}
}
25 changes: 24 additions & 1 deletion src/core/raster/qgsrasterlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,7 @@ void QgsRasterLayer::draw( QPainter * theQPainter,
{
QgsDebugMsg( "PalettedColor drawing type detected..." );

//test
//create color array for renderer
int bNumber = bandNumber( mGrayBandName );
QList<QgsColorRampShader::ColorRampItem> itemList = mRasterStatsList[ bNumber - 1].colorTable;
QColor* colorArray = new QColor[itemList.size()];
Expand All @@ -854,7 +854,17 @@ void QgsRasterLayer::draw( QPainter * theQPainter,
}

QgsPalettedRasterRenderer renderer( mDataProvider, bNumber, colorArray, itemList.size(), mResampler );
//opacity settings for renderer
renderer.setOpacity( mTransparencyLevel / 255.0 );
renderer.setRasterTransparency( &mRasterTransparency );
if ( mTransparencyBandName != TRSTRING_NOT_SET )
{
int tBandNr = bandNumber( mTransparencyBandName );
if ( tBandNr > 0 )
{
renderer.setAlphaBand( tBandNr );
}
}
renderer.draw( theQPainter, theRasterViewPort, theQgsMapToPixel );
#if 0
drawPalettedSingleBandColor( theQPainter, theRasterViewPort,
Expand Down Expand Up @@ -946,6 +956,19 @@ void QgsRasterLayer::draw( QPainter * theQPainter,
int green = bandNumber( mGreenBandName );
int blue = bandNumber( mBlueBandName );
QgsMultiBandColorRenderer r( mDataProvider, red, green, blue, mResampler );

//opacity settings for renderer
r.setOpacity( mTransparencyLevel / 255.0 );
r.setRasterTransparency( &mRasterTransparency );
if ( mTransparencyBandName != TRSTRING_NOT_SET )
{
int tBandNr = bandNumber( mTransparencyBandName );
if ( tBandNr > 0 )
{
r.setAlphaBand( tBandNr );
}
}

r.draw( theQPainter, theRasterViewPort, theQgsMapToPixel );
#if 0
drawMultiBandColor( theQPainter, theRasterViewPort,
Expand Down
8 changes: 7 additions & 1 deletion src/core/raster/qgsrasterrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@
***************************************************************************/

#include "qgsrasterrenderer.h"
#include "qgsrastertransparency.h"
#include "qgsrasterviewport.h"
#include "qgsmaptopixel.h"

QgsRasterRenderer::QgsRasterRenderer( QgsRasterDataProvider* provider, QgsRasterResampler* resampler ): mProvider( provider ), mResampler( resampler ),
mOpacity( 255 )
mOpacity( 1.0 ), mRasterTransparency( 0 ), mAlphaBand( -1 )
{
}

Expand Down Expand Up @@ -147,3 +148,8 @@ void QgsRasterRenderer::removePartInfo( int bandNumber )
mRasterPartInfos.remove( bandNumber );
}
}

bool QgsRasterRenderer::usesTransparency() const
{
return ( mAlphaBand > 0 || ( mRasterTransparency && !mRasterTransparency->isEmpty() ) || !doubleNear( mOpacity, 1.0 ) );
}
18 changes: 17 additions & 1 deletion src/core/raster/qgsrasterrenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
class QPainter;
class QgsMapToPixel;
class QgsRasterResampler;
class QgsRasterTransparency;
class QgsRasterViewPort;

class QgsRasterRenderer
Expand All @@ -45,9 +46,17 @@ class QgsRasterRenderer
virtual ~QgsRasterRenderer();
virtual void draw( QPainter* p, QgsRasterViewPort* viewPort, const QgsMapToPixel* theQgsMapToPixel ) = 0;

bool usesTransparency() const;

void setOpacity( double opacity ) { mOpacity = opacity; }
double opacity() const { return mOpacity; }

void setRasterTransparency( QgsRasterTransparency* t ) { mRasterTransparency = t; }
const QgsRasterTransparency* rasterTransparency() const { return mRasterTransparency; }

void setAlphaBand( int band ) { mAlphaBand = band; }
int alphaBand() const { return mAlphaBand; }

protected:
inline double readValue( void *data, QgsRasterDataProvider::DataType type, int index );

Expand All @@ -59,7 +68,14 @@ class QgsRasterRenderer
QgsRasterDataProvider* mProvider;
QgsRasterResampler* mResampler;
QMap<int, RasterPartInfo> mRasterPartInfos;
double mOpacity; //global alpha value

/**Global alpha value (0-1)*/
double mOpacity;
/**Raster transparency per color or value. Overwrites global alpha value*/
QgsRasterTransparency* mRasterTransparency;
/**Read alpha value from band. Is combined with value from raster transparency / global alpha value.
Default: -1 (not set)*/
int mAlphaBand;

private:
/**Remove part into and release memory*/
Expand Down
5 changes: 5 additions & 0 deletions src/core/raster/qgsrastertransparency.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,8 @@ int QgsRasterTransparency::alphaValue( double theRedValue, double theGreenValue,

return theGlobalTransparency;
}

bool QgsRasterTransparency::isEmpty() const
{
return ( mTransparentThreeValuePixelList.isEmpty() && mTransparentSingleValuePixelList.isEmpty() );
}
3 changes: 3 additions & 0 deletions src/core/raster/qgsrastertransparency.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ class CORE_EXPORT QgsRasterTransparency
/** \brief Return the transparency value for a RGB Pixel */
int alphaValue( double, double, double, int theGlobalTransparency = 255 ) const;

/**True if there are no entries in the pixel lists*/
bool isEmpty() const;

private:
/** \brief The list to hold transparency values for RGB layers */
QList<QgsRasterTransparency::TransparentThreeValuePixel> mTransparentThreeValuePixelList;
Expand Down

0 comments on commit 76cc219

Please sign in to comment.