-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -169,6 +169,7 @@ | |
#include "qgsrasterlayer.h" | ||
#include "qgsrasterlayerproperties.h" | ||
#include "qgsrasternuller.h" | ||
#include "qgsbrightnesscontrastfilter.h" | ||
#include "qgsrasterrenderer.h" | ||
#include "qgsrasterlayersaveasdialog.h" | ||
#include "qgsrectangle.h" | ||
|
@@ -1050,6 +1051,10 @@ void QgisApp::createActions() | |
connect( mActionFullHistogramStretch, SIGNAL( triggered() ), this, SLOT( fullHistogramStretch() ) ); | ||
connect( mActionLocalCumulativeCutStretch, SIGNAL( triggered() ), this, SLOT( localCumulativeCutStretch() ) ); | ||
connect( mActionFullCumulativeCutStretch, SIGNAL( triggered() ), this, SLOT( fullCumulativeCutStretch() ) ); | ||
connect( mActionIncreaseBrightness, SIGNAL( triggered() ), this, SLOT( increaseBrightness() ) ); | ||
connect( mActionDecreaseBrightness, SIGNAL( triggered() ), this, SLOT( decreaseBrightness() ) ); | ||
connect( mActionIncreaseContrast, SIGNAL( triggered() ), this, SLOT( increaseContrast() ) ); | ||
connect( mActionDecreaseContrast, SIGNAL( triggered() ), this, SLOT( decreaseContrast() ) ); | ||
|
||
// Vector Menu Items | ||
connect( mActionOSMDownload, SIGNAL( triggered() ), this, SLOT( osmDownloadDialog() ) ); | ||
|
@@ -1675,6 +1680,10 @@ void QgisApp::setTheme( QString theThemeName ) | |
mActionHelpContents->setIcon( QgsApplication::getThemeIcon( "/mActionHelpContents.png" ) ); | ||
mActionLocalHistogramStretch->setIcon( QgsApplication::getThemeIcon( "/mActionLocalHistogramStretch.png" ) ); | ||
mActionFullHistogramStretch->setIcon( QgsApplication::getThemeIcon( "/mActionFullHistogramStretch.png" ) ); | ||
//~ mActionIncreaseBrightness->setIcon( QgsApplication::getThemeIcon( "/mActionIncreaseBrightness.png" ) ); | ||
//~ mActionDecreaseBrightness->setIcon( QgsApplication::getThemeIcon( "/mActionDecreaseBrightness.png" ) ); | ||
//~ mActionIncreaseContrast->setIcon( QgsApplication::getThemeIcon( "/mActionIncreaseContrast.png" ) ); | ||
//~ mActionDecreaseContrast->setIcon( QgsApplication::getThemeIcon( "/mActionDecreaseContrast.png" ) ); | ||
mActionZoomActualSize->setIcon( QgsApplication::getThemeIcon( "/mActionZoomNative.png" ) ); | ||
mActionQgisHomePage->setIcon( QgsApplication::getThemeIcon( "/mActionQgisHomePage.png" ) ); | ||
mActionAbout->setIcon( QgsApplication::getThemeIcon( "/mActionHelpAbout.png" ) ); | ||
|
@@ -6454,6 +6463,63 @@ void QgisApp::histogramStretch( bool visibleAreaOnly, QgsRasterLayer::ContrastEn | |
mMapCanvas->refresh(); | ||
} | ||
|
||
void QgisApp::increaseBrightness() | ||
{ | ||
adjustBrightnessContrast( 1 ); | ||
} | ||
|
||
void QgisApp::decreaseBrightness() | ||
{ | ||
adjustBrightnessContrast( -1 ); | ||
} | ||
|
||
void QgisApp::increaseContrast() | ||
{ | ||
adjustBrightnessContrast( 1, false ); | ||
} | ||
|
||
void QgisApp::decreaseContrast() | ||
{ | ||
adjustBrightnessContrast( -1, false ); | ||
} | ||
|
||
|
||
void QgisApp::adjustBrightnessContrast( int delta, bool updateBrightness ) | ||
{ | ||
QgsMapLayer * myLayer = mMapLegend->currentLayer(); | ||
|
||
if ( !myLayer ) | ||
{ | ||
QMessageBox::information( this, | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
alexbruy
Author
Contributor
|
||
tr( "No Layer Selected" ), | ||
tr( "To change brightness or contrast, you need to have a raster layer selected." ) ); | ||
return; | ||
} | ||
|
||
QgsRasterLayer* myRasterLayer = qobject_cast<QgsRasterLayer *>( myLayer ); | ||
if ( !myRasterLayer ) | ||
{ | ||
QMessageBox::information( this, | ||
tr( "No Raster Layer Selected" ), | ||
tr( "To change brightness or contrast, you need to have a raster layer selected." ) ); | ||
return; | ||
} | ||
|
||
QgsBrightnessContrastFilter* brightnessFilter = myRasterLayer->brightnessFilter(); | ||
|
||
if ( updateBrightness ) | ||
{ | ||
brightnessFilter->setBrightness( brightnessFilter->brightness() + delta ); | ||
} | ||
else | ||
{ | ||
brightnessFilter->setContrast( brightnessFilter->contrast() + delta ); | ||
} | ||
|
||
myRasterLayer->setCacheImage( NULL ); | ||
mMapCanvas->refresh(); | ||
} | ||
|
||
void QgisApp::helpContents() | ||
{ | ||
openURL( "index.html" ); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,195 @@ | ||
/*************************************************************************** | ||
qgsbrightnesscontrastfilter.cpp | ||
--------------------- | ||
begin : February 2013 | ||
copyright : (C) 2013 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 "qgsbrightnesscontrastfilter.h" | ||
|
||
#include <QDomDocument> | ||
#include <QDomElement> | ||
|
||
|
||
QgsBrightnessContrastFilter::QgsBrightnessContrastFilter( QgsRasterInterface* input ) | ||
: QgsRasterInterface( input ), | ||
mBrightness( 0 ), | ||
mContrast( 0 ) | ||
{ | ||
} | ||
|
||
QgsBrightnessContrastFilter::~QgsBrightnessContrastFilter() | ||
{ | ||
} | ||
|
||
QgsRasterInterface * QgsBrightnessContrastFilter::clone() const | ||
{ | ||
QgsDebugMsg( "Entered" ); | ||
QgsBrightnessContrastFilter * filter = new QgsBrightnessContrastFilter( 0 ); | ||
filter->setBrightness( mBrightness ); | ||
return filter; | ||
} | ||
|
||
int QgsBrightnessContrastFilter::bandCount() const | ||
{ | ||
if ( mOn ) | ||
{ | ||
return 1; | ||
} | ||
|
||
if ( mInput ) | ||
{ | ||
return mInput->bandCount(); | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
QGis::DataType QgsBrightnessContrastFilter::dataType( int bandNo ) const | ||
{ | ||
if ( mOn ) | ||
{ | ||
return QGis::ARGB32_Premultiplied; | ||
} | ||
|
||
if ( mInput ) | ||
{ | ||
return mInput->dataType( bandNo ); | ||
} | ||
|
||
return QGis::UnknownDataType; | ||
} | ||
|
||
bool QgsBrightnessContrastFilter::setInput( QgsRasterInterface* input ) | ||
{ | ||
QgsDebugMsg( "Entered" ); | ||
|
||
// Brightness filter can only work with single band ARGB32_Premultiplied | ||
if ( !input ) | ||
{ | ||
QgsDebugMsg( "No input" ); | ||
return false; | ||
} | ||
|
||
if ( !mOn ) | ||
{ | ||
// In off mode we can connect to anything | ||
QgsDebugMsg( "OK" ); | ||
mInput = input; | ||
return true; | ||
} | ||
|
||
if ( input->bandCount() < 1 ) | ||
{ | ||
QgsDebugMsg( "No input band" ); | ||
return false; | ||
} | ||
|
||
if ( input->dataType( 1 ) != QGis::ARGB32_Premultiplied && | ||
input->dataType( 1 ) != QGis::ARGB32 ) | ||
{ | ||
QgsDebugMsg( "Unknown input data type" ); | ||
return false; | ||
} | ||
|
||
mInput = input; | ||
QgsDebugMsg( "OK" ); | ||
return true; | ||
} | ||
|
||
QgsRasterBlock * QgsBrightnessContrastFilter::block( int bandNo, QgsRectangle const & extent, int width, int height ) | ||
{ | ||
Q_UNUSED( bandNo ); | ||
QgsDebugMsg( "Entered" ); | ||
|
||
QgsRasterBlock *outputBlock = new QgsRasterBlock(); | ||
if ( !mInput ) | ||
{ | ||
return outputBlock; | ||
} | ||
|
||
// At this moment we know that we read rendered image | ||
int bandNumber = 1; | ||
QgsRasterBlock *inputBlock = mInput->block( bandNumber, extent, width, height ); | ||
if ( !inputBlock || inputBlock->isEmpty() ) | ||
{ | ||
QgsDebugMsg( "No raster data!" ); | ||
delete inputBlock; | ||
return outputBlock; | ||
} | ||
|
||
if ( mBrightness == 0 && mContrast == 0 ) | ||
{ | ||
QgsDebugMsg( "No brightness changes." ); | ||
delete outputBlock; | ||
return inputBlock; | ||
} | ||
|
||
if ( !outputBlock->reset( QGis::ARGB32_Premultiplied, width, height ) ) | ||
{ | ||
delete inputBlock; | ||
return outputBlock; | ||
} | ||
|
||
// adjust image | ||
QRgb myNoDataColor = qRgba( 0, 0, 0, 0 ); | ||
QRgb myColor; | ||
int r, g, b; | ||
|
||
double f = ( 259 * ( mContrast + 255 ) ) / ( 255 * ( 259 - mContrast ) ); | ||
|
||
for ( size_t i = 0; i < ( size_t )width*height; i++ ) | ||
{ | ||
if ( inputBlock->color( i ) == myNoDataColor ) | ||
{ | ||
outputBlock->setColor( i, myNoDataColor ); | ||
continue; | ||
} | ||
|
||
myColor = inputBlock->color( i ); | ||
r = qBound( 0, qRound( f * ( qBound( 0, qRed( myColor ) + mBrightness, 255 ) - 128 ) + 128 ), 255 ); | ||
g = qBound( 0, qRound( f * ( qBound( 0, qGreen( myColor ) + mBrightness, 255 ) - 128 ) + 128 ), 255 ); | ||
b = qBound( 0, qRound( f * ( qBound( 0, qBlue( myColor ) + mBrightness, 255 ) - 128 ) + 128 ), 255 ); | ||
|
||
outputBlock->setColor( i, qRgb( r, g, b ) ); | ||
} | ||
|
||
delete inputBlock; | ||
return outputBlock; | ||
} | ||
|
||
void QgsBrightnessContrastFilter::writeXML( QDomDocument& doc, QDomElement& parentElem ) | ||
{ | ||
if ( parentElem.isNull() ) | ||
{ | ||
return; | ||
} | ||
|
||
QDomElement filterElem = doc.createElement( "brightnesscontrast" ); | ||
|
||
filterElem.setAttribute( "brightness", QString::number( mBrightness ) ); | ||
filterElem.setAttribute( "contrast", QString::number( mContrast ) ); | ||
parentElem.appendChild( filterElem ); | ||
} | ||
|
||
void QgsBrightnessContrastFilter::readXML( const QDomElement& filterElem ) | ||
{ | ||
if ( filterElem.isNull() ) | ||
{ | ||
return; | ||
} | ||
|
||
mBrightness = filterElem.attribute( "brightness", "0" ).toInt(); | ||
mContrast = filterElem.attribute( "contrast", "0" ).toInt(); | ||
} |
3 comments
on commit 1145bd2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Alex
I was just playing with this a little - dont you think it would be more useful to have a combo and/or slider widget so that these values can be set precisely? At the moment it requires a lot of clicking - often without any perceptible change in my test image.
Regards
Tim
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Tim
I already thinking about adding sliders to raster properties dialog to allow more precise way to set this parameters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi
I already thinking about adding sliders to raster properties dialog to allow more precise way to set this parameters.
Great. Note I think they should be accompanied by spin boxes to allow precise value entry too.
shouldn't it be better to get QMessageBar instead of QMessageBox for this sort of warnings ?
Btw, thanks for this new feature!