21#include <QDomDocument>
27 , mColorizeColor( QColor::fromRgb( 255, 128, 128 ) )
102 QgsDebugError( QStringLiteral(
"Unknown input data type" ) );
116 std::unique_ptr< QgsRasterBlock > outputBlock(
new QgsRasterBlock() );
119 return outputBlock.release();
124 std::unique_ptr< QgsRasterBlock > inputBlock(
mInput->
block( bandNumber,
extent, width, height, feedback ) );
125 if ( !inputBlock || inputBlock->isEmpty() )
128 return outputBlock.release();
131 if ( !mInvertColors && mSaturation == 0 && mGrayscaleMode ==
GrayscaleOff && !mColorizeOn )
134 return inputBlock.release();
139 return outputBlock.release();
143 QRgb myNoDataColor = qRgba( 0, 0, 0, 0 );
148 double alphaFactor = 1.0;
152 if ( inputBlock->color( i ) == myNoDataColor )
154 outputBlock->setColor( i, myNoDataColor );
158 myRgb = inputBlock->color( i );
159 myColor = QColor( myRgb );
162 alpha = qAlpha( myRgb );
167 outputBlock->setColor( i, myRgb );
172 myColor.getRgb( &r, &g, &b );
174 if ( mInvertColors || alpha != 255 )
180 alphaFactor = alpha / 255.;
191 myColor = QColor::fromRgb( r, g, b );
194 myColor.getHsl( &h, &s, &l );
197 if ( ( mGrayscaleMode !=
GrayscaleOff ) || ( mSaturationScale != 1 ) )
199 processSaturation( r, g, b, h, s, l );
205 processColorization( r, g, b, h, s, l );
217 outputBlock->setColor( i, qRgba( r, g, b, alpha ) );
220 return outputBlock.release();
224void QgsHueSaturationFilter::processColorization(
int &r,
int &g,
int &b,
int &h,
int &s,
int &l )
const
233 QColor colorizedColor = QColor::fromHsl( h, s, l );
235 if ( mColorizeStrength == 100 )
238 myColor = colorizedColor;
241 myColor.getRgb( &r, &g, &b );
246 int colorizedR, colorizedG, colorizedB;
247 colorizedColor.getRgb( &colorizedR, &colorizedG, &colorizedB );
250 double p = ( double ) mColorizeStrength / 100.;
251 r = p * colorizedR + ( 1 - p ) * r;
252 g = p * colorizedG + ( 1 - p ) * g;
253 b = p * colorizedB + ( 1 - p ) * b;
256 myColor = QColor::fromRgb( r, g, b );
257 myColor.getHsl( &h, &s, &l );
262void QgsHueSaturationFilter::processSaturation(
int &r,
int &g,
int &b,
int &h,
int &s,
int &l )
268 switch ( mGrayscaleMode )
276 myColor = QColor::fromHsl( h, s, l );
277 myColor.getRgb( &r, &g, &b );
283 int luminosity = 0.21 * r + 0.72 * g + 0.07 * b;
284 r = g = b = luminosity;
287 myColor = QColor::fromRgb( r, g, b );
288 myColor.getHsl( &h, &s, &l );
294 int average = ( r + g + b ) / 3;
298 myColor = QColor::fromRgb( r, g, b );
299 myColor.getHsl( &h, &s, &l );
305 if ( mSaturationScale < 1 )
308 s = std::min( (
int )( s * mSaturationScale ), 255 );
314 s = std::min( (
int )( 255. * ( 1 - std::pow( 1 - ( s / 255. ), std::pow( mSaturationScale, 2 ) ) ) ), 255 );
318 myColor = QColor::fromHsl( h, s, l );
319 myColor.getRgb( &r, &g, &b );
327 mSaturation = std::clamp(
saturation, -100, 100 );
330 mSaturationScale = ( ( double ) mSaturation / 100 ) + 1;
338 mColorizeH = mColorizeColor.hue();
339 mColorizeS = mColorizeColor.saturation();
344 if ( parentElem.isNull() )
349 QDomElement filterElem = doc.createElement( QStringLiteral(
"huesaturation" ) );
351 filterElem.setAttribute( QStringLiteral(
"saturation" ), QString::number( mSaturation ) );
352 filterElem.setAttribute( QStringLiteral(
"grayscaleMode" ), QString::number( mGrayscaleMode ) );
353 filterElem.setAttribute( QStringLiteral(
"invertColors" ), QString::number( mInvertColors ) );
354 filterElem.setAttribute( QStringLiteral(
"colorizeOn" ), QString::number( mColorizeOn ) );
355 filterElem.setAttribute( QStringLiteral(
"colorizeRed" ), QString::number( mColorizeColor.red() ) );
356 filterElem.setAttribute( QStringLiteral(
"colorizeGreen" ), QString::number( mColorizeColor.green() ) );
357 filterElem.setAttribute( QStringLiteral(
"colorizeBlue" ), QString::number( mColorizeColor.blue() ) );
358 filterElem.setAttribute( QStringLiteral(
"colorizeStrength" ), QString::number( mColorizeStrength ) );
360 parentElem.appendChild( filterElem );
365 if ( filterElem.isNull() )
370 setSaturation( filterElem.attribute( QStringLiteral(
"saturation" ), QStringLiteral(
"0" ) ).toInt() );
372 mInvertColors =
static_cast< bool >( filterElem.attribute( QStringLiteral(
"invertColors" ), QStringLiteral(
"0" ) ).toInt() );
374 mColorizeOn =
static_cast< bool >( filterElem.attribute( QStringLiteral(
"colorizeOn" ), QStringLiteral(
"0" ) ).toInt() );
375 int mColorizeRed = filterElem.attribute( QStringLiteral(
"colorizeRed" ), QStringLiteral(
"255" ) ).toInt();
376 int mColorizeGreen = filterElem.attribute( QStringLiteral(
"colorizeGreen" ), QStringLiteral(
"128" ) ).toInt();
377 int mColorizeBlue = filterElem.attribute( QStringLiteral(
"colorizeBlue" ), QStringLiteral(
"128" ) ).toInt();
378 setColorizeColor( QColor::fromRgb( mColorizeRed, mColorizeGreen, mColorizeBlue ) );
379 mColorizeStrength = filterElem.attribute( QStringLiteral(
"colorizeStrength" ), QStringLiteral(
"100" ) ).toInt();
DataType
Raster data types.
@ ARGB32_Premultiplied
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
@ UnknownDataType
Unknown or unspecified type.
@ ARGB32
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32.
Color and saturation filter pipe for rasters.
void setColorizeOn(bool colorizeOn)
void setSaturation(int saturation)
void setGrayscaleMode(QgsHueSaturationFilter::GrayscaleMode grayscaleMode)
QgsHueSaturationFilter(QgsRasterInterface *input=nullptr)
Qgis::DataType dataType(int bandNo) const override
Returns data type for the band specified by number.
QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr) override
Read block of data using given extent and size.
QgsHueSaturationFilter * clone() const override
Clone itself, create deep copy.
void setInvertColors(bool invertColors)
Sets whether the filter will invert colors.
void setColorizeColor(const QColor &colorizeColor)
void setColorizeStrength(int colorizeStrength)
int bandCount() const override
Gets number of bands.
QColor colorizeColor() const
void readXml(const QDomElement &filterElem) override
Sets base class members from xml. Usually called from create() methods of subclasses.
void writeXml(QDomDocument &doc, QDomElement &parentElem) const override
Write base class members to xml.
bool setInput(QgsRasterInterface *input) override
Set input.
Feedback object tailored for raster block reading.
Base class for processing filters like renderers, reprojector, resampler etc.
virtual QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr)=0
Read block of data using given extent and size.
virtual Qgis::DataType dataType(int bandNo) const =0
Returns data type for the band specified by number.
virtual int bandCount() const =0
Gets number of bands.
QgsRasterInterface * mInput
virtual QgsRectangle extent() const
Gets the extent of the interface.
virtual QgsRasterInterface * input() const
Current input.
A rectangle specified with double values.
Q_INVOKABLE QString toString(int precision=16) const
Returns a string representation of form xmin,ymin : xmax,ymax Coordinates will be truncated to the sp...
unsigned long long qgssize
Qgssize is used instead of size_t, because size_t is stdlib type, unknown by SIP, and it would be har...
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)