From 85fbeb26f8cbb0a82ffd8a4ef80b318eb157c373 Mon Sep 17 00:00:00 2001 From: Asger Skovbo Petersen Date: Wed, 8 Jun 2016 13:30:00 +0200 Subject: [PATCH] Hillshaderenderer: Fix transparency effects (#3185) --- src/core/raster/qgshillshaderenderer.cpp | 54 +++++++++++++++++++++++- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/src/core/raster/qgshillshaderenderer.cpp b/src/core/raster/qgshillshaderenderer.cpp index df52b1061b8..d1a6d900de5 100644 --- a/src/core/raster/qgshillshaderenderer.cpp +++ b/src/core/raster/qgshillshaderenderer.cpp @@ -18,7 +18,7 @@ #include #include "qgshillshaderenderer.h" - +#include "qgsrastertransparency.h" #include "qgsrasterinterface.h" #include "qgsrasterblock.h" #include "qgsrectangle.h" @@ -40,6 +40,10 @@ QgsHillshadeRenderer *QgsHillshadeRenderer::clone() const QgsHillshadeRenderer* r = new QgsHillshadeRenderer( nullptr, mBand, mLightAzimuth, mLightAngle ); r->setZFactor( mZFactor ); r->setMultiDirectional( mMultiDirectional ); + // "Effects" + r->setOpacity( mOpacity ); + r->setAlphaBand( mAlphaBand ); + r->setRasterTransparency( mRasterTransparency ? new QgsRasterTransparency( *mRasterTransparency ) : nullptr ); return r; } @@ -98,12 +102,34 @@ QgsRasterBlock *QgsHillshadeRenderer::block( int bandNo, const QgsRectangle &ext return outputBlock; } + QgsRasterBlock *alphaBlock = nullptr; + + if ( mAlphaBand > 0 && mBand != mAlphaBand ) + { + + alphaBlock = mInput->block( mAlphaBand, extent, width, height ); + if ( !alphaBlock || alphaBlock->isEmpty() ) + { + // TODO: better to render without alpha + delete inputBlock; + delete alphaBlock; + return outputBlock; + } + } + else if ( mAlphaBand > 0 ) + { + alphaBlock = inputBlock; + } + if ( !outputBlock->reset( QGis::ARGB32_Premultiplied, width, height ) ) { delete inputBlock; + delete alphaBlock; return outputBlock; } + + double cellXSize = extent.width() / double( width ); double cellYSize = extent.height() / double( height ); double zenithRad = qMax( 0.0, 90 - mLightAngle ) * M_PI / 180.0; @@ -224,9 +250,33 @@ QgsRasterBlock *QgsHillshadeRenderer::block( int bandNo, const QgsRectangle &ext double color3 = cosSlope + sinSlope * cos( angle3Rad - aspectRad ) ; grayValue = qBound( 0.0, 255 * ( weight0 * color0 + weight1 * color1 + weight2 * color2 + weight3 * color3 ) * 0.5, 255.0 ); } - outputBlock->setColor( i, j, qRgb( grayValue, grayValue, grayValue ) ); + + double currentAlpha = mOpacity; + if ( mRasterTransparency ) + { + currentAlpha = mRasterTransparency->alphaValue( x22, mOpacity * 255 ) / 255.0; + } + if ( mAlphaBand > 0 ) + { + currentAlpha *= alphaBlock->value( i ) / 255.0; + } + + if ( qgsDoubleNear( currentAlpha, 1.0 ) ) + { + outputBlock->setColor( i, j, qRgba( grayValue, grayValue, grayValue, 255 ) ); + } + else + { + outputBlock->setColor( i, j, qRgba( currentAlpha * grayValue, currentAlpha * grayValue, currentAlpha * grayValue, currentAlpha * 255 ) ); + } } } + + delete inputBlock; + if ( mAlphaBand > 0 && mBand != mAlphaBand ) + { + delete alphaBlock; + } return outputBlock; }