21 #include <QDomDocument> 
   22 #include <QDomElement> 
   97     QgsDebugMsg( QStringLiteral( 
"Unknown input data type" ) );
 
  111   std::unique_ptr< QgsRasterBlock > outputBlock( 
new QgsRasterBlock() );
 
  114     return outputBlock.release();
 
  119   std::unique_ptr< QgsRasterBlock > inputBlock( 
mInput->
block( bandNumber, 
extent, width, height, feedback ) );
 
  120   if ( !inputBlock || inputBlock->isEmpty() )
 
  122     QgsDebugMsg( QStringLiteral( 
"No raster data!" ) );
 
  123     return outputBlock.release();
 
  126   if ( mBrightness == 0 && mContrast == 0 && mGamma == 1.0 )
 
  128     QgsDebugMsgLevel( QStringLiteral( 
"No brightness/contrast/gamma changes." ), 4 );
 
  129     return inputBlock.release();
 
  134     return outputBlock.release();
 
  138   QRgb myNoDataColor = qRgba( 0, 0, 0, 0 );
 
  142   double f = std::pow( ( mContrast + 100 ) / 100.0, 2 );
 
  143   double gammaCorrection = 1.0 / mGamma;
 
  147     if ( inputBlock->color( i ) == myNoDataColor )
 
  149       outputBlock->setColor( i, myNoDataColor );
 
  153     myColor = inputBlock->color( i );
 
  154     alpha = qAlpha( myColor );
 
  156     r = adjustColorComponent( qRed( myColor ), alpha, mBrightness, f, gammaCorrection );
 
  157     g = adjustColorComponent( qGreen( myColor ), alpha, mBrightness, f, gammaCorrection );
 
  158     b = adjustColorComponent( qBlue( myColor ), alpha, mBrightness, f, gammaCorrection );
 
  160     outputBlock->setColor( i, qRgba( r, g, b, alpha ) );
 
  163   return outputBlock.release();
 
  168   mBrightness = std::clamp( 
brightness, -255, 255 );
 
  173   mContrast = std::clamp( 
contrast, -100, 100 );
 
  178   mGamma = std::clamp( 
gamma, 0.1, 10.0 );
 
  181 int QgsBrightnessContrastFilter::adjustColorComponent( 
int colorComponent, 
int alpha, 
int brightness, 
double contrastFactor, 
double gammaCorrection )
 const 
  186     return std::clamp( ( 
int )( 255 * std::pow( ( ( ( ( ( ( colorComponent / 255.0 ) - 0.5 ) * contrastFactor ) + 0.5 ) * 255 ) + 
brightness ) / 255.0, gammaCorrection ) ), 0, 255 );
 
  188   else if ( alpha == 0 )
 
  197     double alphaFactor = alpha / 255.;
 
  198     double adjustedColor = colorComponent / alphaFactor;
 
  201     return alphaFactor * std::clamp( 255 * std::pow( ( ( ( ( ( ( adjustedColor / 255.0 ) - 0.5 ) * contrastFactor ) + 0.5 ) * 255 ) + 
brightness ) / 255, gammaCorrection ), 0., 255. );
 
  207   if ( parentElem.isNull() )
 
  212   QDomElement filterElem = doc.createElement( QStringLiteral( 
"brightnesscontrast" ) );
 
  214   filterElem.setAttribute( QStringLiteral( 
"brightness" ), QString::number( mBrightness ) );
 
  215   filterElem.setAttribute( QStringLiteral( 
"contrast" ), QString::number( mContrast ) );
 
  216   filterElem.setAttribute( QStringLiteral( 
"gamma" ), QString::number( mGamma ) );
 
  217   parentElem.appendChild( filterElem );
 
  222   if ( filterElem.isNull() )
 
  227   mBrightness = filterElem.attribute( QStringLiteral( 
"brightness" ), QStringLiteral( 
"0" ) ).toInt();
 
  228   mContrast = filterElem.attribute( QStringLiteral( 
"contrast" ), QStringLiteral( 
"0" ) ).toInt();
 
  229   mGamma = filterElem.attribute( QStringLiteral( 
"gamma" ), QStringLiteral( 
"1" ) ).toDouble();
 
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.
Brightness/contrast and gamma correction filter pipe for rasters.
int contrast() const
Returns current contrast level.
int bandCount() const override
Gets number of bands.
QgsBrightnessContrastFilter * clone() const override
Clone itself, create deep copy.
bool setInput(QgsRasterInterface *input) override
Set input.
QgsBrightnessContrastFilter(QgsRasterInterface *input=nullptr)
int brightness() const
Returns current brightness level.
double gamma() const
Returns current gamma value.
void readXml(const QDomElement &filterElem) override
Sets base class members from xml. Usually called from create() methods of subclasses.
QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr) override
Read block of data using given extent and size.
void setGamma(double gamma)
Set gamma value.
void setContrast(int contrast)
Set contrast level.
void writeXml(QDomDocument &doc, QDomElement &parentElem) const override
Write base class members to xml.
void setBrightness(int brightness)
Set brightness level.
Qgis::DataType dataType(int bandNo) const override
Returns data type for the band specified by number.
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 QgsRasterInterface * input() const
Current input.
virtual int bandCount() const =0
Gets number of bands.
QgsRasterInterface * mInput
virtual QgsRectangle extent() const
Gets the extent of the interface.
A rectangle specified with double values.
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)