22#include <QDomDocument>
49 return mInput->bandCount();
64 return mInput->dataType( bandNo );
89 if (
input->bandCount() < 1 )
110 QgsDebugMsgLevel( QStringLiteral(
"width = %1 height = %2 extent = %3" ).arg( width ).arg( height ).arg(
extent.toString() ), 4 );
112 auto outputBlock = std::make_unique<QgsRasterBlock>();
115 return outputBlock.release();
120 std::unique_ptr< QgsRasterBlock > inputBlock(
mInput->block( bandNumber,
extent, width, height, feedback ) );
121 if ( !inputBlock || inputBlock->isEmpty() )
124 return outputBlock.release();
127 if ( mBrightness == 0 && mContrast == 0 && mGamma == 1.0 )
129 QgsDebugMsgLevel( QStringLiteral(
"No brightness/contrast/gamma changes." ), 4 );
130 return inputBlock.release();
135 return outputBlock.release();
139 QRgb myNoDataColor = qRgba( 0, 0, 0, 0 );
143 double f = std::pow( ( mContrast + 100 ) / 100.0, 2 );
144 double gammaCorrection = 1.0 / mGamma;
148 if ( inputBlock->color( i ) == myNoDataColor )
150 outputBlock->setColor( i, myNoDataColor );
154 myColor = inputBlock->color( i );
155 alpha = qAlpha( myColor );
157 r = adjustColorComponent( qRed( myColor ), alpha, mBrightness, f, gammaCorrection );
158 g = adjustColorComponent( qGreen( myColor ), alpha, mBrightness, f, gammaCorrection );
159 b = adjustColorComponent( qBlue( myColor ), alpha, mBrightness, f, gammaCorrection );
161 outputBlock->setColor( i, qRgba( r, g, b, alpha ) );
164 return outputBlock.release();
169 mBrightness = std::clamp(
brightness, -255, 255 );
174 mContrast = std::clamp(
contrast, -100, 100 );
179 mGamma = std::clamp(
gamma, 0.1, 10.0 );
182int QgsBrightnessContrastFilter::adjustColorComponent(
int colorComponent,
int alpha,
int brightness,
double contrastFactor,
double gammaCorrection )
const
187 return std::clamp( (
int )( 255 * std::pow( ( ( ( ( ( ( colorComponent / 255.0 ) - 0.5 ) * contrastFactor ) + 0.5 ) * 255 ) +
brightness ) / 255.0, gammaCorrection ) ), 0, 255 );
189 else if ( alpha == 0 )
198 double alphaFactor = alpha / 255.;
199 double adjustedColor = colorComponent / alphaFactor;
202 return alphaFactor * std::clamp( 255 * std::pow( ( ( ( ( ( ( adjustedColor / 255.0 ) - 0.5 ) * contrastFactor ) + 0.5 ) * 255 ) +
brightness ) / 255, gammaCorrection ), 0., 255. );
208 if ( parentElem.isNull() )
213 QDomElement filterElem = doc.createElement( QStringLiteral(
"brightnesscontrast" ) );
215 filterElem.setAttribute( QStringLiteral(
"brightness" ), QString::number( mBrightness ) );
216 filterElem.setAttribute( QStringLiteral(
"contrast" ), QString::number( mContrast ) );
217 filterElem.setAttribute( QStringLiteral(
"gamma" ), QString::number( mGamma ) );
218 parentElem.appendChild( filterElem );
223 if ( filterElem.isNull() )
228 mBrightness = filterElem.attribute( QStringLiteral(
"brightness" ), QStringLiteral(
"0" ) ).toInt();
229 mContrast = filterElem.attribute( QStringLiteral(
"contrast" ), QStringLiteral(
"0" ) ).toInt();
230 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.
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.
QgsRasterInterface(QgsRasterInterface *input=nullptr)
QgsRasterInterface * mInput
virtual QgsRectangle extent() const
Gets the extent of the interface.
virtual QgsRasterInterface * input() const
Current input.
A rectangle specified with double values.
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)