21#include <QDomDocument> 
   27  , mColorizeColor( QColor::fromRgb( 255, 128, 128 ) )
 
 
  102    QgsDebugError( QStringLiteral( 
"Unknown input data type" ) );
 
 
  123  std::unique_ptr< QgsRasterBlock > inputBlock( 
mInput->
block( bandNumber, 
extent, width, height, feedback ) );
 
  124  if ( !inputBlock || inputBlock->isEmpty() )
 
  130  if ( !mInvertColors && mSaturation == 0 && mGrayscaleMode == 
GrayscaleOff && !mColorizeOn )
 
  133    return inputBlock.release();
 
  136  auto outputBlock = std::make_unique<QgsRasterBlock>();
 
  144  const QRgb myNoDataColor = qRgba( 0, 0, 0, 0 );
 
  147  double alphaFactor = 1.0;
 
  149  const QRgb *inputColorData = inputBlock->colorData();
 
  150  const int imageHeight = inputBlock->image().height();
 
  151  const int imageWidth = inputBlock->image().width();
 
  153  QRgb *outputColorData = outputBlock->colorData();
 
  155  for ( 
int row = 0; row < height; ++row )
 
  160    for ( 
int col = 0; col < width; ++col )
 
  164      if ( !inputColorData || row >= imageHeight || col >= imageWidth || inputColorData[i] == myNoDataColor )
 
  166        outputColorData[i] = myNoDataColor;
 
  170      const QRgb inputColor = inputColorData[i];
 
  171      QColor myColor = QColor( inputColor );
 
  174      const int alpha = qAlpha( inputColor );
 
  179        outputColorData[i] = inputColor;
 
  184      myColor.getRgb( &r, &g, &b );
 
  186      if ( mInvertColors || alpha != 255 )
 
  192          alphaFactor = alpha / 255.;
 
  203        myColor = QColor::fromRgb( r, g, b );
 
  206      myColor.getHsl( &h, &s, &l );
 
  209      if ( ( mGrayscaleMode != 
GrayscaleOff ) || ( mSaturationScale != 1 ) )
 
  211        processSaturation( r, g, b, h, s, l );
 
  217        processColorization( r, g, b, h, s, l );
 
  229      outputColorData[i] = qRgba( r, g, b, alpha );
 
  233  return outputBlock.release();
 
 
  237void QgsHueSaturationFilter::processColorization( 
int &r, 
int &g, 
int &b, 
int &h, 
int &s, 
int &l )
 const 
  246  QColor colorizedColor = QColor::fromHsl( h, s, l );
 
  248  if ( mColorizeStrength == 100 )
 
  251    myColor = colorizedColor;
 
  254    myColor.getRgb( &r, &g, &b );
 
  259    int colorizedR, colorizedG, colorizedB;
 
  260    colorizedColor.getRgb( &colorizedR, &colorizedG, &colorizedB );
 
  263    double p = ( double ) mColorizeStrength / 100.;
 
  264    r = p * colorizedR + ( 1 - p ) * r;
 
  265    g = p * colorizedG + ( 1 - p ) * g;
 
  266    b = p * colorizedB + ( 1 - p ) * b;
 
  269    myColor = QColor::fromRgb( r, g, b );
 
  270    myColor.getHsl( &h, &s, &l );
 
  275void QgsHueSaturationFilter::processSaturation( 
int &r, 
int &g, 
int &b, 
int &h, 
int &s, 
int &l )
 
  281  switch ( mGrayscaleMode )
 
  289      myColor = QColor::fromHsl( h, s, l );
 
  290      myColor.getRgb( &r, &g, &b );
 
  296      int luminosity = 0.21 * r + 0.72 * g + 0.07 * b;
 
  297      r = g = b = luminosity;
 
  300      myColor = QColor::fromRgb( r, g, b );
 
  301      myColor.getHsl( &h, &s, &l );
 
  307      int average = ( r + g + b ) / 3;
 
  311      myColor = QColor::fromRgb( r, g, b );
 
  312      myColor.getHsl( &h, &s, &l );
 
  318      if ( mSaturationScale < 1 )
 
  321        s = std::min( ( 
int )( s * mSaturationScale ), 255 );
 
  327        s = std::min( ( 
int )( 255. * ( 1 - std::pow( 1 - ( s / 255. ), std::pow( mSaturationScale, 2 ) ) ) ), 255 );
 
  331      myColor = QColor::fromHsl( h, s, l );
 
  332      myColor.getRgb( &r, &g, &b );
 
  340  mSaturation = std::clamp( 
saturation, -100, 100 );
 
  343  mSaturationScale = ( ( double ) mSaturation / 100 ) + 1;
 
 
  351  mColorizeH = mColorizeColor.hue();
 
  352  mColorizeS = mColorizeColor.saturation();
 
 
  357  if ( parentElem.isNull() )
 
  362  QDomElement filterElem = doc.createElement( QStringLiteral( 
"huesaturation" ) );
 
  364  filterElem.setAttribute( QStringLiteral( 
"saturation" ), QString::number( mSaturation ) );
 
  365  filterElem.setAttribute( QStringLiteral( 
"grayscaleMode" ), QString::number( mGrayscaleMode ) );
 
  366  filterElem.setAttribute( QStringLiteral( 
"invertColors" ), QString::number( mInvertColors ) );
 
  367  filterElem.setAttribute( QStringLiteral( 
"colorizeOn" ), QString::number( mColorizeOn ) );
 
  368  filterElem.setAttribute( QStringLiteral( 
"colorizeRed" ), QString::number( mColorizeColor.red() ) );
 
  369  filterElem.setAttribute( QStringLiteral( 
"colorizeGreen" ), QString::number( mColorizeColor.green() ) );
 
  370  filterElem.setAttribute( QStringLiteral( 
"colorizeBlue" ), QString::number( mColorizeColor.blue() ) );
 
  371  filterElem.setAttribute( QStringLiteral( 
"colorizeStrength" ), QString::number( mColorizeStrength ) );
 
  373  parentElem.appendChild( filterElem );
 
 
  378  if ( filterElem.isNull() )
 
  383  setSaturation( filterElem.attribute( QStringLiteral( 
"saturation" ), QStringLiteral( 
"0" ) ).toInt() );
 
  385  mInvertColors = 
static_cast< bool >( filterElem.attribute( QStringLiteral( 
"invertColors" ), QStringLiteral( 
"0" ) ).toInt() );
 
  387  mColorizeOn = 
static_cast< bool >( filterElem.attribute( QStringLiteral( 
"colorizeOn" ), QStringLiteral( 
"0" ) ).toInt() );
 
  388  int mColorizeRed = filterElem.attribute( QStringLiteral( 
"colorizeRed" ), QStringLiteral( 
"255" ) ).toInt();
 
  389  int mColorizeGreen = filterElem.attribute( QStringLiteral( 
"colorizeGreen" ), QStringLiteral( 
"128" ) ).toInt();
 
  390  int mColorizeBlue = filterElem.attribute( QStringLiteral( 
"colorizeBlue" ), QStringLiteral( 
"128" ) ).toInt();
 
  391  setColorizeColor( QColor::fromRgb( mColorizeRed, mColorizeGreen, mColorizeBlue ) );
 
  392  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.
 
bool isCanceled() const
Tells whether the operation has been canceled already.
 
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)