move gamma correction code inside brightness/contrast filter

This commit is contained in:
Alexander Bruy 2020-06-29 11:27:41 +03:00
parent cfa5c5bf83
commit 0214b4f01a
22 changed files with 72 additions and 497 deletions

View File

@ -13,7 +13,7 @@
class QgsBrightnessContrastFilter : QgsRasterInterface
{
%Docstring
Brightness/contrast filter pipe for rasters.
Brightness/contrast and gamma correction filter pipe for rasters.
%End
%TypeHeaderCode
@ -43,6 +43,9 @@ Brightness/contrast filter pipe for rasters.
void setContrast( int contrast );
int contrast() const;
void setGamma( double gamma );
double gamma() const;
virtual void writeXml( QDomDocument &doc, QDomElement &parentElem ) const;

View File

@ -1,62 +0,0 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/raster/qgsgammacorrectionfilter.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
class QgsGammaCorrectionFilter : QgsRasterInterface
{
%Docstring
Gamma correction filter pipe for rasters.
.. versionadded:: 3.16
%End
%TypeHeaderCode
#include "qgsgammacorrectionfilter.h"
%End
public:
QgsGammaCorrectionFilter( QgsRasterInterface *input = 0 );
virtual QgsGammaCorrectionFilter *clone() const /Factory/;
virtual int bandCount() const;
virtual Qgis::DataType dataType( int bandNo ) const;
virtual bool setInput( QgsRasterInterface *input );
virtual QgsRasterBlock *block( int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback = 0 ) /Factory/;
void setGamma( double gamma );
double gamma() const;
virtual void writeXml( QDomDocument &doc, QDomElement &parentElem ) const;
virtual void readXml( const QDomElement &filterElem );
%Docstring
Sets base class members from xml. Usually called from :py:func:`~QgsGammaCorrectionFilter.create` methods of subclasses
%End
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/raster/qgsgammacorrectionfilter.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/

View File

@ -95,7 +95,6 @@ Base class for processing filters like renderers, reprojector, resampler etc.
#include "qgsrasterinterface.h"
// QgsRasterInterface subclasses
#include <qgsbrightnesscontrastfilter.h>
#include <qgsgammacorrectionfilter.h>
#include <qgshuesaturationfilter.h>
#include <qgsrasterdataprovider.h>
#include <qgsrasternuller.h>
@ -116,8 +115,6 @@ Base class for processing filters like renderers, reprojector, resampler etc.
sipType = sipType_QgsBrightnessContrastFilter;
else if ( dynamic_cast<QgsHueSaturationFilter *>( sipCpp ) )
sipType = sipType_QgsHueSaturationFilter;
else if ( dynamic_cast<QgsGammaCorrectionFilter *>( sipCpp ) )
sipType = sipType_QgsGammaCorrectionFilter;
else if ( dynamic_cast<QgsRasterDataProvider *>( sipCpp ) )
{
sipType = sipType_QgsRasterDataProvider;

View File

@ -190,8 +190,6 @@ Returns the raster's resample filter.
.. seealso:: :py:func:`brightnessFilter`
.. seealso:: :py:func:`gammaCorrectionFilter`
.. seealso:: :py:func:`hueSaturationFilter`
%End
@ -201,22 +199,7 @@ Returns the raster's brightness/contrast filter.
.. seealso:: :py:func:`resampleFilter`
.. seealso:: :py:func:`gammaCorrectionFilter`
.. seealso:: :py:func:`hueSaturationFilter`
%End
QgsGammaCorrectionFilter *gammaCorrectionFilter() const;
%Docstring
Returns the raster's gamma correction filter.
.. seealso:: :py:func:`resampleFilter`
.. seealso:: :py:func:`brightnessFilter`
.. seealso:: :py:func:`hueSaturationFilter`
.. versionadded:: 3.16
%End
QgsHueSaturationFilter *hueSaturationFilter() const;
@ -226,8 +209,6 @@ Returns the raster's hue/saturation filter.
.. seealso:: :py:func:`resampleFilter`
.. seealso:: :py:func:`brightnessFilter`
.. seealso:: :py:func:`gammaCorrectionFilter`
%End
void setResamplingStage( QgsRasterPipe::ResamplingStage stage );

View File

@ -31,7 +31,6 @@ Base class for processing modules.
ProjectorRole,
NullerRole,
HueSaturationRole,
GammaCorrectionRole
};
QgsRasterPipe();
@ -103,13 +102,6 @@ Test if interface at index may be switched on/off
QgsRasterRenderer *renderer() const;
QgsRasterResampleFilter *resampleFilter() const;
QgsBrightnessContrastFilter *brightnessFilter() const;
QgsGammaCorrectionFilter *gammaCorrectionFilter() const;
%Docstring
Returns gamma correction filter pipe
.. versionadded:: 3.16
%End
QgsHueSaturationFilter *hueSaturationFilter() const;
QgsRasterProjector *projector() const;
QgsRasterNuller *nuller() const;

View File

@ -468,7 +468,6 @@
%Include auto_generated/raster/qgscontrastenhancement.sip
%Include auto_generated/raster/qgscontrastenhancementfunction.sip
%Include auto_generated/raster/qgscubicrasterresampler.sip
%Include auto_generated/raster/qgsgammacorrectionfilter.sip
%Include auto_generated/raster/qgshillshaderenderer.sip
%Include auto_generated/raster/qgshuesaturationfilter.sip
%Include auto_generated/raster/qgslinearminmaxenhancement.sip

View File

@ -315,7 +315,6 @@ Q_GUI_EXPORT extern int qt_defaultDpiX();
#include "qgsrasterlayerproperties.h"
#include "qgsrasternuller.h"
#include "qgsbrightnesscontrastfilter.h"
#include "qgsgammacorrectionfilter.h"
#include "qgsrasterrenderer.h"
#include "qgsrasterlayersaveasdialog.h"
#include "qgsrasterprojector.h"
@ -12257,8 +12256,8 @@ void QgisApp::adjustGamma( double delta )
return;
}
QgsGammaCorrectionFilter *gammaFilter = rasterLayer->gammaCorrectionFilter();
gammaFilter->setGamma( gammaFilter->gamma() + delta );
QgsBrightnessContrastFilter *brightnessFilter = rasterLayer->brightnessFilter();
brightnessFilter->setGamma( brightnessFilter->gamma() + delta );
rasterLayer->triggerRepaint();
}

View File

@ -2120,7 +2120,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
//! Do histogram stretch for singleband gray / multiband color rasters
void histogramStretch( bool visibleAreaOnly = false, QgsRasterMinMaxOrigin::Limits limits = QgsRasterMinMaxOrigin::MinMax );
//! Apply raster brightness
//! Apply raster brightness/contrast
void adjustBrightnessContrast( int delta, bool updateBrightness = true );
/**

View File

@ -572,7 +572,6 @@ SET(QGIS_CORE_SRCS
raster/qgsbilinearrasterresampler.cpp
raster/qgsbrightnesscontrastfilter.cpp
raster/qgscubicrasterresampler.cpp
raster/qgsgammacorrectionfilter.cpp
raster/qgshuesaturationfilter.cpp
raster/qgsmultibandcolorrenderer.cpp
raster/qgspalettedrasterrenderer.cpp
@ -1307,7 +1306,6 @@ SET(QGIS_CORE_HDRS
raster/qgscontrastenhancement.h
raster/qgscontrastenhancementfunction.h
raster/qgscubicrasterresampler.h
raster/qgsgammacorrectionfilter.h
raster/qgshillshaderenderer.h
raster/qgshuesaturationfilter.h
raster/qgslinearminmaxenhancement.h

View File

@ -32,6 +32,7 @@ QgsBrightnessContrastFilter *QgsBrightnessContrastFilter::clone() const
QgsBrightnessContrastFilter *filter = new QgsBrightnessContrastFilter( nullptr );
filter->setBrightness( mBrightness );
filter->setContrast( mContrast );
filter->setGamma( mGamma );
return filter;
}
@ -122,9 +123,9 @@ QgsRasterBlock *QgsBrightnessContrastFilter::block( int bandNo, QgsRectangle co
return outputBlock.release();
}
if ( mBrightness == 0 && mContrast == 0 )
if ( mBrightness == 0 && mContrast == 0 && mGamma == 1.0 )
{
QgsDebugMsgLevel( QStringLiteral( "No brightness changes." ), 4 );
QgsDebugMsgLevel( QStringLiteral( "No brightness/contrast/gamma changes." ), 4 );
return inputBlock.release();
}
@ -139,6 +140,7 @@ QgsRasterBlock *QgsBrightnessContrastFilter::block( int bandNo, QgsRectangle co
int r, g, b, alpha;
double f = std::pow( ( mContrast + 100 ) / 100.0, 2 );
double gammaCorrection = 1.0 / mGamma;
for ( qgssize i = 0; i < ( qgssize )width * height; i++ )
{
@ -151,9 +153,9 @@ QgsRasterBlock *QgsBrightnessContrastFilter::block( int bandNo, QgsRectangle co
myColor = inputBlock->color( i );
alpha = qAlpha( myColor );
r = adjustColorComponent( qRed( myColor ), alpha, mBrightness, f );
g = adjustColorComponent( qGreen( myColor ), alpha, mBrightness, f );
b = adjustColorComponent( qBlue( myColor ), alpha, mBrightness, f );
r = adjustColorComponent( qRed( myColor ), alpha, mBrightness, f, gammaCorrection );
g = adjustColorComponent( qGreen( myColor ), alpha, mBrightness, f, gammaCorrection );
b = adjustColorComponent( qBlue( myColor ), alpha, mBrightness, f, gammaCorrection );
outputBlock->setColor( i, qRgba( r, g, b, alpha ) );
}
@ -161,12 +163,12 @@ QgsRasterBlock *QgsBrightnessContrastFilter::block( int bandNo, QgsRectangle co
return outputBlock.release();
}
int QgsBrightnessContrastFilter::adjustColorComponent( int colorComponent, int alpha, int brightness, double contrastFactor ) const
int QgsBrightnessContrastFilter::adjustColorComponent( int colorComponent, int alpha, int brightness, double contrastFactor, double gammaCorrection ) const
{
if ( alpha == 255 )
{
// Opaque pixel, do simpler math
return qBound( 0, ( int )( ( ( ( ( ( colorComponent / 255.0 ) - 0.5 ) * contrastFactor ) + 0.5 ) * 255 ) + brightness ), 255 );
return qBound( 0, ( int )( 255 * std::pow( ( ( ( ( ( ( colorComponent / 255.0 ) - 0.5 ) * contrastFactor ) + 0.5 ) * 255 ) + brightness ) / 255.0, gammaCorrection ) ), 255 );
}
else if ( alpha == 0 )
{
@ -181,7 +183,7 @@ int QgsBrightnessContrastFilter::adjustColorComponent( int colorComponent, int a
double adjustedColor = colorComponent / alphaFactor;
// Make sure to return a premultiplied color
return alphaFactor * qBound( 0., ( ( ( ( ( ( adjustedColor / 255.0 ) - 0.5 ) * contrastFactor ) + 0.5 ) * 255 ) + brightness ), 255. );
return alphaFactor * qBound( 0., std::pow( ( ( ( ( ( ( adjustedColor / 255.0 ) - 0.5 ) * contrastFactor ) + 0.5 ) * 255 ) + brightness ) / 255, gammaCorrection ), 255. );
}
}
@ -196,6 +198,7 @@ void QgsBrightnessContrastFilter::writeXml( QDomDocument &doc, QDomElement &pare
filterElem.setAttribute( QStringLiteral( "brightness" ), QString::number( mBrightness ) );
filterElem.setAttribute( QStringLiteral( "contrast" ), QString::number( mContrast ) );
filterElem.setAttribute( QStringLiteral( "gamma" ), QString::number( mGamma ) );
parentElem.appendChild( filterElem );
}
@ -208,4 +211,5 @@ void QgsBrightnessContrastFilter::readXml( const QDomElement &filterElem )
mBrightness = filterElem.attribute( QStringLiteral( "brightness" ), QStringLiteral( "0" ) ).toInt();
mContrast = filterElem.attribute( QStringLiteral( "contrast" ), QStringLiteral( "0" ) ).toInt();
mGamma = filterElem.attribute( QStringLiteral( "gamma" ), QStringLiteral( "1" ) ).toDouble();
}

View File

@ -26,7 +26,7 @@ class QDomElement;
/**
* \ingroup core
* Brightness/contrast filter pipe for rasters.
* Brightness/contrast and gamma correction filter pipe for rasters.
*/
class CORE_EXPORT QgsBrightnessContrastFilter : public QgsRasterInterface
{
@ -49,20 +49,27 @@ class CORE_EXPORT QgsBrightnessContrastFilter : public QgsRasterInterface
void setContrast( int contrast ) { mContrast = qBound( -100, contrast, 100 ); }
int contrast() const { return mContrast; }
void setGamma( double gamma ) { mGamma = qBound( 0.1, gamma, 10.0 ); }
double gamma() const { return mGamma; }
void writeXml( QDomDocument &doc, QDomElement &parentElem ) const override;
//! Sets base class members from xml. Usually called from create() methods of subclasses
void readXml( const QDomElement &filterElem ) override;
private:
//! Adjusts a color component by the specified brightness and contrast factor
int adjustColorComponent( int colorComponent, int alpha, int brightness, double contrastFactor ) const;
//! Adjusts a color component by the specified brightness, contrast factor and gamma correction
int adjustColorComponent( int colorComponent, int alpha, int brightness, double contrastFactor, double gammaCorrection ) const;
//! Current brightness coefficient value. Default: 0. Range: -255...255
int mBrightness = 0;
//! Current contrast coefficient value. Default: 0. Range: -100...100
double mContrast = 0;
int mContrast = 0;
//! Current gamma value. Default: 1. Range: 0.1…10.0
double mGamma = 1.0;
};
#endif // QGSBRIGHTNESSCONTRASTFILTER_H

View File

@ -1,208 +0,0 @@
/***************************************************************************
qgsgammacorrectionfilter.cpp
---------------------
begin : June 2020
copyright : (C) 2020 by Alexander Bruy
email : alexander dot bruy at gmail dot com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsrasterdataprovider.h"
#include "qgsgammacorrectionfilter.h"
#include <QDomDocument>
#include <QDomElement>
QgsGammaCorrectionFilter::QgsGammaCorrectionFilter( QgsRasterInterface *input )
: QgsRasterInterface( input )
{
}
QgsGammaCorrectionFilter *QgsGammaCorrectionFilter::clone() const
{
QgsDebugMsgLevel( QStringLiteral( "Entered" ), 4 );
QgsGammaCorrectionFilter *filter = new QgsGammaCorrectionFilter( nullptr );
filter->setGamma( mGamma );
return filter;
}
int QgsGammaCorrectionFilter::bandCount() const
{
if ( mOn )
{
return 1;
}
if ( mInput )
{
return mInput->bandCount();
}
return 0;
}
Qgis::DataType QgsGammaCorrectionFilter::dataType( int bandNo ) const
{
if ( mOn )
{
return Qgis::ARGB32_Premultiplied;
}
if ( mInput )
{
return mInput->dataType( bandNo );
}
return Qgis::UnknownDataType;
}
bool QgsGammaCorrectionFilter::setInput( QgsRasterInterface *input )
{
QgsDebugMsgLevel( QStringLiteral( "Entered" ), 4 );
// Gamma correction filter can only work with single band ARGB32_Premultiplied
if ( !input )
{
QgsDebugMsgLevel( QStringLiteral( "No input" ), 4 );
return false;
}
if ( !mOn )
{
// In off mode we can connect to anything
QgsDebugMsgLevel( QStringLiteral( "OK" ), 4 );
mInput = input;
return true;
}
if ( input->bandCount() < 1 )
{
QgsDebugMsg( QStringLiteral( "No input band" ) );
return false;
}
if ( input->dataType( 1 ) != Qgis::ARGB32_Premultiplied &&
input->dataType( 1 ) != Qgis::ARGB32 )
{
QgsDebugMsg( QStringLiteral( "Unknown input data type" ) );
return false;
}
mInput = input;
QgsDebugMsgLevel( QStringLiteral( "OK" ), 4 );
return true;
}
QgsRasterBlock *QgsGammaCorrectionFilter::block( int bandNo, QgsRectangle const &extent, int width, int height, QgsRasterBlockFeedback *feedback )
{
Q_UNUSED( bandNo )
QgsDebugMsgLevel( QStringLiteral( "width = %1 height = %2 extent = %3" ).arg( width ).arg( height ).arg( extent.toString() ), 4 );
std::unique_ptr< QgsRasterBlock > outputBlock( new QgsRasterBlock() );
if ( !mInput )
{
return outputBlock.release();
}
// At this moment we know that we read rendered image
int bandNumber = 1;
std::unique_ptr< QgsRasterBlock > inputBlock( mInput->block( bandNumber, extent, width, height, feedback ) );
if ( !inputBlock || inputBlock->isEmpty() )
{
QgsDebugMsg( QStringLiteral( "No raster data!" ) );
return outputBlock.release();
}
if ( mGamma == 1.0 )
{
QgsDebugMsgLevel( QStringLiteral( "No gamma changes." ), 4 );
return inputBlock.release();
}
if ( !outputBlock->reset( Qgis::ARGB32_Premultiplied, width, height ) )
{
return outputBlock.release();
}
// adjust image
QRgb myNoDataColor = qRgba( 0, 0, 0, 0 );
QRgb myColor;
int r, g, b, alpha;
double gammaCorrection = 1.0 / mGamma;
for ( qgssize i = 0; i < ( qgssize )width * height; i++ )
{
if ( inputBlock->color( i ) == myNoDataColor )
{
outputBlock->setColor( i, myNoDataColor );
continue;
}
myColor = inputBlock->color( i );
alpha = qAlpha( myColor );
r = adjustColorComponent( qRed( myColor ), alpha, gammaCorrection );
g = adjustColorComponent( qGreen( myColor ), alpha, gammaCorrection );
b = adjustColorComponent( qBlue( myColor ), alpha, gammaCorrection );
outputBlock->setColor( i, qRgba( r, g, b, alpha ) );
}
return outputBlock.release();
}
int QgsGammaCorrectionFilter::adjustColorComponent( int colorComponent, int alpha, double gammaCorrection ) const
{
if ( alpha == 255 )
{
// Opaque pixel, do simpler math
return qBound( 0, ( int )( 255 * std::pow( colorComponent / 255.0, gammaCorrection ) ), 255 );
}
else if ( alpha == 0 )
{
// Totally transparent pixel
return 0;
}
else
{
// Semi-transparent pixel. We need to adjust the math since we are using Qgis::ARGB32_Premultiplied
// and color values have been premultiplied by alpha
double alphaFactor = alpha / 255.;
double adjustedColor = colorComponent / alphaFactor;
// Make sure to return a premultiplied color
return alphaFactor * qBound( 0., 255 * std::pow( adjustedColor / 255.0, gammaCorrection ), 255. );
}
}
void QgsGammaCorrectionFilter::writeXml( QDomDocument &doc, QDomElement &parentElem ) const
{
if ( parentElem.isNull() )
{
return;
}
QDomElement filterElem = doc.createElement( QStringLiteral( "gammacorrection" ) );
filterElem.setAttribute( QStringLiteral( "gamma" ), QString::number( mGamma ) );
parentElem.appendChild( filterElem );
}
void QgsGammaCorrectionFilter::readXml( const QDomElement &filterElem )
{
if ( filterElem.isNull() )
{
return;
}
mGamma = filterElem.attribute( QStringLiteral( "gamma" ), QStringLiteral( "1" ) ).toDouble();
}

View File

@ -1,63 +0,0 @@
/***************************************************************************
qgsgammacorrectionfilter.h
-------------------
begin : June 2020
copyright : (C) 2020 by Alexander Bruy
email : alexander dot bruy at gmail dot com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSGAMMACORRECTIONFILTER_H
#define QGSGAMMACORRECTIONFILTER_H
#include "qgis_core.h"
#include "qgis_sip.h"
#include "qgsrasterinterface.h"
class QDomElement;
/**
* \ingroup core
* Gamma correction filter pipe for rasters.
* \since QGIS 3.16
*/
class CORE_EXPORT QgsGammaCorrectionFilter : public QgsRasterInterface
{
public:
QgsGammaCorrectionFilter( QgsRasterInterface *input = nullptr );
QgsGammaCorrectionFilter *clone() const override SIP_FACTORY;
int bandCount() const override;
Qgis::DataType dataType( int bandNo ) const override;
bool setInput( QgsRasterInterface *input ) override;
QgsRasterBlock *block( int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback = nullptr ) override SIP_FACTORY;
void setGamma( double gamma ) { mGamma = qBound( 0.1, gamma, 10.0 ); }
double gamma() const { return mGamma; }
void writeXml( QDomDocument &doc, QDomElement &parentElem ) const override;
//! Sets base class members from xml. Usually called from create() methods of subclasses
void readXml( const QDomElement &filterElem ) override;
private:
//! Adjusts a color component by the specified gamma correction value
int adjustColorComponent( int colorComponent, int alpha, double gammaCorrection ) const;
//! Current gamma value. Default: 1. Range: 0.1…10.0
double mGamma = 1.0;
};
#endif // QGSGAMMACORRECTIONFILTER_H

View File

@ -118,7 +118,6 @@ class CORE_EXPORT QgsRasterInterface
#ifdef SIP_RUN
// QgsRasterInterface subclasses
#include <qgsbrightnesscontrastfilter.h>
#include <qgsgammacorrectionfilter.h>
#include <qgshuesaturationfilter.h>
#include <qgsrasterdataprovider.h>
#include <qgsrasternuller.h>
@ -142,8 +141,6 @@ class CORE_EXPORT QgsRasterInterface
sipType = sipType_QgsBrightnessContrastFilter;
else if ( dynamic_cast<QgsHueSaturationFilter *>( sipCpp ) )
sipType = sipType_QgsHueSaturationFilter;
else if ( dynamic_cast<QgsGammaCorrectionFilter *>( sipCpp ) )
sipType = sipType_QgsGammaCorrectionFilter;
else if ( dynamic_cast<QgsRasterDataProvider *>( sipCpp ) )
{
sipType = sipType_QgsRasterDataProvider;

View File

@ -20,7 +20,6 @@ email : tim at linfiniti.com
#include "qgscoordinatereferencesystem.h"
#include "qgscoordinatetransform.h"
#include "qgsdatasourceuri.h"
#include "qgsgammacorrectionfilter.h"
#include "qgshuesaturationfilter.h"
#include "qgslayermetadataformatter.h"
#include "qgslogger.h"
@ -776,10 +775,6 @@ void QgsRasterLayer::setDataProvider( QString const &provider, const QgsDataProv
QgsHueSaturationFilter *hueSaturationFilter = new QgsHueSaturationFilter();
mPipe.set( hueSaturationFilter );
// gamma correction filter
QgsGammaCorrectionFilter *gammaFilter = new QgsGammaCorrectionFilter();
mPipe.set( gammaFilter );
// resampler (must be after renderer)
QgsRasterResampleFilter *resampleFilter = new QgsRasterResampleFilter();
mPipe.set( resampleFilter );
@ -1832,17 +1827,6 @@ bool QgsRasterLayer::readSymbology( const QDomNode &layer_node, QString &errorMe
hueSaturationFilter->readXml( hueSaturationElem );
}
//gamma correction
QgsGammaCorrectionFilter *gammaFilter = new QgsGammaCorrectionFilter();
mPipe.set( gammaFilter );
//saturation coefficient
QDomElement gammaElem = pipeNode.firstChildElement( QStringLiteral( "gammacorrection" ) );
if ( !gammaElem.isNull() )
{
gammaFilter->readXml( gammaElem );
}
//resampler
QgsRasterResampleFilter *resampleFilter = new QgsRasterResampleFilter();
mPipe.set( resampleFilter );

View File

@ -250,7 +250,6 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
* Returns the raster's resample filter.
*
* \see brightnessFilter()
* \see gammaCorrectionFilter()
* \see hueSaturationFilter()
*/
QgsRasterResampleFilter *resampleFilter() const { return mPipe.resampleFilter(); }
@ -259,28 +258,15 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
* Returns the raster's brightness/contrast filter.
*
* \see resampleFilter()
* \see gammaCorrectionFilter()
* \see hueSaturationFilter()
*/
QgsBrightnessContrastFilter *brightnessFilter() const { return mPipe.brightnessFilter(); }
/**
* Returns the raster's gamma correction filter.
*
* \see resampleFilter()
* \see brightnessFilter()
* \see hueSaturationFilter()
*
* \since QGIS 3.16
*/
QgsGammaCorrectionFilter *gammaCorrectionFilter() const { return mPipe.gammaCorrectionFilter(); }
/**
* Returns the raster's hue/saturation filter.
*
* \see resampleFilter()
* \see brightnessFilter()
* \see gammaCorrectionFilter()
*/
QgsHueSaturationFilter *hueSaturationFilter() const { return mPipe.hueSaturationFilter(); }

View File

@ -25,7 +25,6 @@
#include "qgsrasterrenderer.h"
#include "qgsrasterresamplefilter.h"
#include "qgsbrightnesscontrastfilter.h"
#include "qgsgammacorrectionfilter.h"
#include "qgshuesaturationfilter.h"
#include "qgsrasterprojector.h"
#include "qgsrasternuller.h"
@ -140,7 +139,6 @@ QgsRasterPipe::Role QgsRasterPipe::interfaceRole( QgsRasterInterface *interface
else if ( dynamic_cast<QgsRasterResampleFilter *>( interface ) ) role = ResamplerRole;
else if ( dynamic_cast<QgsBrightnessContrastFilter *>( interface ) ) role = BrightnessRole;
else if ( dynamic_cast<QgsHueSaturationFilter *>( interface ) ) role = HueSaturationRole;
else if ( dynamic_cast<QgsGammaCorrectionFilter *>( interface ) ) role = GammaCorrectionRole;
else if ( dynamic_cast<QgsRasterProjector *>( interface ) ) role = ProjectorRole;
else if ( dynamic_cast<QgsRasterNuller *>( interface ) ) role = NullerRole;
@ -193,7 +191,6 @@ bool QgsRasterPipe::set( QgsRasterInterface *interface )
int resamplerIdx = mRoleMap.value( ResamplerRole, -1 );
int brightnessIdx = mRoleMap.value( BrightnessRole, -1 );
int hueSaturationIdx = mRoleMap.value( HueSaturationRole, -1 );
int gammaCorrectionIdx = mRoleMap.value( GammaCorrectionRole, -1 );
if ( role == ProviderRole )
{
@ -211,17 +208,13 @@ bool QgsRasterPipe::set( QgsRasterInterface *interface )
{
idx = std::max( std::max( providerIdx, rendererIdx ), brightnessIdx ) + 1;
}
else if ( role == GammaCorrectionRole )
else if ( role == ResamplerRole )
{
idx = std::max( std::max( std::max( providerIdx, rendererIdx ), brightnessIdx ), hueSaturationIdx ) + 1;
}
else if ( role == ResamplerRole )
{
idx = std::max( std::max( std::max( std::max( providerIdx, rendererIdx ), brightnessIdx ), hueSaturationIdx ), gammaCorrectionIdx ) + 1;
}
else if ( role == ProjectorRole )
{
idx = std::max( std::max( std::max( std::max( std::max( providerIdx, rendererIdx ), brightnessIdx ), hueSaturationIdx ), gammaCorrectionIdx ), resamplerIdx ) + 1;
idx = std::max( std::max( std::max( std::max( providerIdx, rendererIdx ), brightnessIdx ), hueSaturationIdx ), resamplerIdx ) + 1;
}
return insert( idx, interface ); // insert may still fail and return false
@ -257,11 +250,6 @@ QgsBrightnessContrastFilter *QgsRasterPipe::brightnessFilter() const
return dynamic_cast<QgsBrightnessContrastFilter *>( interface( BrightnessRole ) );
}
QgsGammaCorrectionFilter *QgsRasterPipe::gammaCorrectionFilter() const
{
return dynamic_cast<QgsGammaCorrectionFilter *>( interface( GammaCorrectionRole ) );
}
QgsHueSaturationFilter *QgsRasterPipe::hueSaturationFilter() const
{
return dynamic_cast<QgsHueSaturationFilter *>( interface( HueSaturationRole ) );

View File

@ -28,7 +28,6 @@ class QgsRasterInterface;
class QgsRasterRenderer;
class QgsRasterResampleFilter;
class QgsBrightnessContrastFilter;
class QgsGammaCorrectionFilter;
class QgsHueSaturationFilter;
class QgsRasterProjector;
class QgsRasterNuller;
@ -58,7 +57,6 @@ class CORE_EXPORT QgsRasterPipe
ProjectorRole = 5,
NullerRole = 6,
HueSaturationRole = 7,
GammaCorrectionRole = 8
};
/**
@ -129,12 +127,6 @@ class CORE_EXPORT QgsRasterPipe
QgsRasterRenderer *renderer() const;
QgsRasterResampleFilter *resampleFilter() const;
QgsBrightnessContrastFilter *brightnessFilter() const;
/**
* Returns gamma correction filter pipe
* \since QGIS 3.16
*/
QgsGammaCorrectionFilter *gammaCorrectionFilter() const;
QgsHueSaturationFilter *hueSaturationFilter() const;
QgsRasterProjector *projector() const;
QgsRasterNuller *nuller() const;

View File

@ -21,7 +21,6 @@
#include "qgsgui.h"
#include "qgsapplication.h"
#include "qgsbrightnesscontrastfilter.h"
#include "qgsgammacorrectionfilter.h"
#include "qgscontrastenhancement.h"
#include "qgscoordinatetransform.h"
#include "qgsprojectionselectiondialog.h"
@ -761,19 +760,13 @@ void QgsRasterLayerProperties::sync()
* Style tab
*/
//set brightness and contrast
//set brightness, contrast and gamma
QgsBrightnessContrastFilter *brightnessFilter = mRasterLayer->brightnessFilter();
if ( brightnessFilter )
{
mSliderBrightness->setValue( brightnessFilter->brightness() );
mSliderContrast->setValue( brightnessFilter->contrast() );
}
//set gamma
QgsGammaCorrectionFilter *gammaFilter = mRasterLayer->gammaCorrectionFilter();
if ( gammaFilter )
{
mGammaSpinBox->setValue( gammaFilter->gamma() );
mGammaSpinBox->setValue( brightnessFilter->gamma() );
}
/*
@ -938,7 +931,7 @@ void QgsRasterLayerProperties::apply()
mRasterLayer->brightnessFilter()->setBrightness( mSliderBrightness->value() );
mRasterLayer->brightnessFilter()->setContrast( mSliderContrast->value() );
mRasterLayer->gammaCorrectionFilter()->setGamma( mGammaSpinBox->value() );
mRasterLayer->brightnessFilter()->setGamma( mGammaSpinBox->value() );
QgsDebugMsg( QStringLiteral( "processing transparency tab" ) );
/*
@ -2324,7 +2317,7 @@ void QgsRasterLayerProperties::mResetColorRenderingBtn_clicked()
mBlendModeComboBox->setBlendMode( QPainter::CompositionMode_SourceOver );
mSliderBrightness->setValue( 0 );
mSliderContrast->setValue( 0 );
mGammaSpinBox->setValue( 1 );
mGammaSpinBox->setValue( 1.0 );
sliderSaturation->setValue( 0 );
comboGrayscale->setCurrentIndex( ( int ) QgsHueSaturationFilter::GrayscaleOff );
mColorizeCheck->setChecked( false );

View File

@ -18,7 +18,6 @@
#include "qgsmapcanvas.h"
#include "qgsbrightnesscontrastfilter.h"
#include "qgshuesaturationfilter.h"
#include "qgsgammacorrectionfilter.h"
#include "qgsrastercontourrendererwidget.h"
#include "qgsrasterlayer.h"
#include "qgsrasterrendererwidget.h"
@ -131,11 +130,7 @@ void QgsRendererRasterPropertiesWidget::apply()
{
brightnessFilter->setBrightness( mSliderBrightness->value() );
brightnessFilter->setContrast( mSliderContrast->value() );
}
if ( QgsGammaCorrectionFilter *gammaFilter = mRasterLayer->gammaCorrectionFilter() )
{
gammaFilter->setGamma( mGammaSpinBox->value() );
brightnessFilter->setGamma( mGammaSpinBox->value() );
}
if ( QgsRasterRendererWidget *rendererWidget = dynamic_cast<QgsRasterRendererWidget *>( stackedWidget->currentWidget() ) )
@ -198,11 +193,7 @@ void QgsRendererRasterPropertiesWidget::syncToLayer( QgsRasterLayer *layer )
{
mSliderBrightness->setValue( brightnessFilter->brightness() );
mSliderContrast->setValue( brightnessFilter->contrast() );
}
if ( QgsGammaCorrectionFilter *gammaFilter = mRasterLayer->gammaCorrectionFilter() )
{
mGammaSpinBox->setValue( gammaFilter->gamma() );
mGammaSpinBox->setValue( brightnessFilter->gamma() );
}
btnColorizeColor->setColorDialogTitle( tr( "Select Color" ) );

View File

@ -237,8 +237,7 @@ ACCEPTABLE_MISSING_DOCS = {
"QgsGroupBoxCollapseButton": ["QgsGroupBoxCollapseButton(QWidget *parent=nullptr)", "setAltDown(bool updown)", "setShiftDown(bool shiftdown)", "shiftDown() const", "altDown() const"],
"QgsConditionalStyle": ["QgsConditionalStyle(const QgsConditionalStyle &other)", "QgsConditionalStyle(const QString &rule)"],
"QgsGeometryFollowBoundariesCheck": ["factoryDescription()", "QgsGeometryFollowBoundariesCheck(QgsGeometryCheckContext *context, const QVariantMap &configuration, QgsVectorLayer *checkLayer)", "factoryCompatibleGeometryTypes()", "factoryCheckType()", "factoryId()", "factoryIsCompatible(QgsVectorLayer *layer)"],
"QgsBrightnessContrastFilter": ["brightness() const", "setBrightness(int brightness)", "contrast() const", "QgsBrightnessContrastFilter(QgsRasterInterface *input=nullptr)", "setContrast(int contrast)"],
"QgsGammaCorrectionFilter": ["gamma() const", "setGamma(double gamma)", "QgsGammaCorrectionFilter(QgsRasterInterface *input=nullptr)"],
"QgsBrightnessContrastFilter": ["brightness() const", "setBrightness(int brightness)", "contrast() const", "QgsBrightnessContrastFilter(QgsRasterInterface *input=nullptr)", "setContrast(int contrast)", "gamma() const", "setGamma(double gamma)"],
"QgsDxfPaintDevice": ["setShift(QPointF shift)", "QgsDxfPaintDevice(QgsDxfExport *dxf)", "setDrawingSize(QSizeF size)", "setLayer(const QString &layer)", "setOutputSize(const QRectF &r)"],
"QgsLongLongValidator": ["top() const", "QgsLongLongValidator(QObject *parent)", "setTop(qint64 top)", "bottom() const", "setRange(qint64 bottom, qint64 top)", "QgsLongLongValidator(qint64 bottom, qint64 top, QObject *parent)", "setBottom(qint64 bottom)"],
"QgsHueSaturationFilter": ["QgsHueSaturationFilter(QgsRasterInterface *input=nullptr)", "colorizeStrength() const", "colorizeColor() const", "saturation() const", "setSaturation(int saturation)", "setColorizeOn(bool colorizeOn)", "setColorizeStrength(int colorizeStrength)", "colorizeOn() const", "GrayscaleMode", "grayscaleMode() const", "setColorizeColor(const QColor &colorizeColor)", "setGrayscaleMode(QgsHueSaturationFilter::GrayscaleMode grayscaleMode)"],

View File

@ -448,41 +448,8 @@ class TestQgsRasterLayer(unittest.TestCase):
self.assertTrue(checker.runTest("expected_paletted_renderer_band3"), "Paletted rendering test failed")
def testGammaCorrection(self):
""" test raster gamma correction filter"""
path = os.path.join(unitTestDataPath(),
'landsat-int16-b1.tif')
info = QFileInfo(path)
base_name = info.baseName()
layer = QgsRasterLayer(path, base_name)
self.assertTrue(layer.isValid(), 'Raster not loaded: {}'.format(path))
layer.gammaCorrectionFilter().setGamma(0.22)
ms = QgsMapSettings()
ms.setLayers([layer])
ms.setExtent(layer.extent())
checker = QgsRenderChecker()
checker.setControlName("expected_raster_gamma022")
checker.setMapSettings(ms)
self.assertTrue(checker.runTest("expected_raster_gamma022"), "Gamma correction (gamma = 0.22) rendering test failed")
layer.gammaCorrectionFilter().setGamma(2.22)
ms = QgsMapSettings()
ms.setLayers([layer])
ms.setExtent(layer.extent())
checker = QgsRenderChecker()
checker.setControlName("expected_raster_gamma222")
checker.setMapSettings(ms)
self.assertTrue(checker.runTest("expected_raster_gamma222"), "Gamma correction (gamma = 2.22) rendering test failed")
def testBrightnessContrast(self):
""" test raster brightness/contrast filter"""
def testBrightnessContrastGamma(self):
""" test raster brightness/contrast/gamma filter"""
path = os.path.join(unitTestDataPath(),
'landsat_4326.tif')
info = QFileInfo(path)
@ -539,6 +506,37 @@ class TestQgsRasterLayer(unittest.TestCase):
self.assertTrue(checker.runTest("expected_raster_brightness20"), "Brightness (b = -20) rendering test failed")
path = os.path.join(unitTestDataPath(),
'landsat-int16-b1.tif')
info = QFileInfo(path)
base_name = info.baseName()
layer = QgsRasterLayer(path, base_name)
self.assertTrue(layer.isValid(), 'Raster not loaded: {}'.format(path))
layer.brightnessFilter().setGamma(0.22)
ms = QgsMapSettings()
ms.setLayers([layer])
ms.setExtent(layer.extent())
checker = QgsRenderChecker()
checker.setControlName("expected_raster_gamma022")
checker.setMapSettings(ms)
self.assertTrue(checker.runTest("expected_raster_gamma022"), "Gamma correction (gamma = 0.22) rendering test failed")
layer.brightnessFilter().setGamma(2.22)
ms = QgsMapSettings()
ms.setLayers([layer])
ms.setExtent(layer.extent())
checker = QgsRenderChecker()
checker.setControlName("expected_raster_gamma222")
checker.setMapSettings(ms)
self.assertTrue(checker.runTest("expected_raster_gamma222"), "Gamma correction (gamma = 2.22) rendering test failed")
def testPalettedColorTableToClassData(self):
entries = [QgsColorRampShader.ColorRampItem(5, QColor(255, 0, 0), 'item1'),
QgsColorRampShader.ColorRampItem(3, QColor(0, 255, 0), 'item2'),