cumulative cut tools, raster stretching moved from qgisapp to raster layer, unfortunately one control image has also be changed because stretching changed from GDALComputeRasterMinMax which gives for tests/testdata/landsat.tif 3. band min/max 57/157 to GDALComputeRasterStatistics which gives 51/172

This commit is contained in:
Radim Blazek 2012-07-29 14:06:02 +02:00
parent ad9cb9d194
commit 80c251d2a9
13 changed files with 196 additions and 181 deletions

View File

@ -79,6 +79,7 @@
<file>themes/default/mActionFormAnnotation.png</file>
<file>themes/default/mActionFreezeLabels.png</file>
<file>themes/default/mActionFromSelectedFeature.png</file>
<file>themes/default/mActionFullCumulativeCutStretch.png</file>
<file>themes/default/mActionFullHistogramStretch.png</file>
<file>themes/default/mActionGroupItems.png</file>
<file>themes/default/mActionHelpAbout.png</file>
@ -91,6 +92,7 @@
<file>themes/default/mActionInvertSelection.png</file>
<file>themes/default/mActionLabeling.png</file>
<file>themes/default/mActionLabel.png</file>
<file>themes/default/mActionLocalCumulativeCutStretch.png</file>
<file>themes/default/mActionLocalHistogramStretch.png</file>
<file>themes/default/mActionLowerItems.png</file>
<file>themes/default/mActionMapTips.png</file>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -963,6 +963,8 @@ void QgisApp::createActions()
// Raster toolbar items
connect( mActionLocalHistogramStretch, SIGNAL( triggered() ), this, SLOT( localHistogramStretch() ) );
connect( mActionFullHistogramStretch, SIGNAL( triggered() ), this, SLOT( fullHistogramStretch() ) );
connect( mActionLocalCumulativeCutStretch, SIGNAL( triggered() ), this, SLOT( localCumulativeCutStretch() ) );
connect( mActionFullCumulativeCutStretch, SIGNAL( triggered() ), this, SLOT( fullCumulativeCutStretch() ) );
// Help Menu Items
@ -5461,14 +5463,29 @@ void QgisApp::options()
void QgisApp::fullHistogramStretch()
{
histogramStretch( false );
histogramStretch( false, QgsRasterLayer::ContrastEnhancementMinMax );
}
void QgisApp::histogramStretch( bool visibleAreaOnly )
void QgisApp::localHistogramStretch()
{
QgsMapLayer * layer = mMapLegend->currentLayer();
histogramStretch( true, QgsRasterLayer::ContrastEnhancementMinMax );
}
if ( !layer )
void QgisApp::fullCumulativeCutStretch()
{
histogramStretch( false, QgsRasterLayer::ContrastEnhancementCumulativeCut );
}
void QgisApp::localCumulativeCutStretch()
{
histogramStretch( true, QgsRasterLayer::ContrastEnhancementCumulativeCut );
}
void QgisApp::histogramStretch( bool visibleAreaOnly, QgsRasterLayer::ContrastEnhancementLimits theLimits )
{
QgsMapLayer * myLayer = mMapLegend->currentLayer();
if ( !myLayer )
{
QMessageBox::information( this,
tr( "No Layer Selected" ),
@ -5476,8 +5493,8 @@ void QgisApp::histogramStretch( bool visibleAreaOnly )
return;
}
QgsRasterLayer* rlayer = qobject_cast<QgsRasterLayer *>( layer );
if ( !rlayer )
QgsRasterLayer* myRasterLayer = qobject_cast<QgsRasterLayer *>( myLayer );
if ( !myRasterLayer )
{
QMessageBox::information( this,
tr( "No Raster Layer Selected" ),
@ -5485,118 +5502,14 @@ void QgisApp::histogramStretch( bool visibleAreaOnly )
return;
}
QgsRasterDataProvider* provider = rlayer->dataProvider();
if ( !provider )
{
return;
}
QgsRectangle myRectangle;
if ( visibleAreaOnly ) myRectangle = mMapCanvas->mapRenderer()->outputExtentToLayerExtent( myRasterLayer, mMapCanvas->extent() );
//get renderer
QgsRasterRenderer* renderer = rlayer->renderer();
if ( !renderer )
{
return;
}
//singleband gray <-> multiband color
if ( renderer->type() == "singlebandgray" )
{
QgsSingleBandGrayRenderer* grayRenderer = static_cast<QgsSingleBandGrayRenderer*>( renderer );
if ( !grayRenderer )
{
return;
}
//create new contrast enhancements
int grayBand = grayRenderer->grayBand();
if ( grayBand == -1 )
{
return;
}
QgsContrastEnhancement* e = rasterContrastEnhancement( rlayer, grayBand, visibleAreaOnly );
if ( !e )
{
return;
}
grayRenderer->setContrastEnhancement( e );
}
else if ( renderer->type() == "multibandcolor" )
{
QgsMultiBandColorRenderer* colorRenderer = static_cast<QgsMultiBandColorRenderer*>( renderer );
if ( !colorRenderer )
{
return;
}
QgsContrastEnhancement* redEnhancement = rasterContrastEnhancement( rlayer, colorRenderer->redBand(), visibleAreaOnly );
if ( redEnhancement )
{
colorRenderer->setRedContrastEnhancement( redEnhancement );
}
QgsContrastEnhancement* greenEnhancement = rasterContrastEnhancement( rlayer, colorRenderer->greenBand(), visibleAreaOnly );
if ( greenEnhancement )
{
colorRenderer->setGreenContrastEnhancement( greenEnhancement );
}
QgsContrastEnhancement* blueEnhancement = rasterContrastEnhancement( rlayer, colorRenderer->blueBand(), visibleAreaOnly );
if ( blueEnhancement )
{
colorRenderer->setBlueContrastEnhancement( blueEnhancement );
}
}
else
{
return;
}
myRasterLayer->setContrastEnhancementAlgorithm( QgsContrastEnhancement::StretchToMinimumMaximum, theLimits, myRectangle );
mMapCanvas->refresh();
}
QgsContrastEnhancement* QgisApp::rasterContrastEnhancement( QgsRasterLayer* rlayer, int band,
bool visibleAreaOnly ) const
{
if ( !rlayer || band == -1 )
{
return 0;
}
QgsRasterDataProvider* provider = rlayer->dataProvider();
if ( !provider )
{
return 0;
}
QgsContrastEnhancement* e = new QgsContrastEnhancement(( QgsContrastEnhancement::QgsRasterDataType )(
provider->dataType( band ) ) );
double minValue = 0;
double maxValue = 0;
if ( visibleAreaOnly )
{
double minMax[2];
rlayer->computeMinimumMaximumFromLastExtent( band, minMax );
minValue = minMax[0];
maxValue = minMax[1];
}
else
{
QgsRasterBandStats rasterBandStats = rlayer->dataProvider()->bandStatistics( band );
minValue = rasterBandStats.minimumValue;
maxValue = rasterBandStats.maximumValue;
}
e->setMinimumValue( minValue );
e->setMaximumValue( maxValue );
e->setContrastEnhancementAlgorithm( QgsContrastEnhancement::StretchToMinimumMaximum );
return e;
}
void QgisApp::localHistogramStretch()
{
histogramStretch( true );
}
void QgisApp::helpContents()
{
openURL( "index.html" );

View File

@ -55,7 +55,6 @@ class QgsPalLabeling;
class QgsPoint;
class QgsProviderRegistry;
class QgsPythonUtils;
class QgsRasterLayer;
class QgsRectangle;
class QgsUndoWidget;
class QgsVectorLayer;
@ -87,6 +86,7 @@ class QgsTileScaleWidget;
#include "qgsconfig.h"
#include "qgsfeature.h"
#include "qgspoint.h"
#include "qgsrasterlayer.h"
#include "qgssnappingdialog.h"
#include "ui_qgisapp.h"
@ -548,6 +548,10 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
* Valid for non wms raster layers only.
* @note Added in QGIS 1.7 */
void fullHistogramStretch();
/** Perform a local cumulative cut stretch */
void localCumulativeCutStretch();
/** Perform a full extent cumulative cut stretch */
void fullCumulativeCutStretch();
//! plugin manager
void showPluginManager();
//! load python support if possible
@ -992,10 +996,7 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
void createDecorations();
/**Do histogram stretch for singleband gray / multiband color rasters*/
void histogramStretch( bool visibleAreaOnly = false );
/**Create raster enhancement object for a raster band*/
QgsContrastEnhancement* rasterContrastEnhancement( QgsRasterLayer* rlayer, int band,
bool visibleAreaOnly = false ) const;
void histogramStretch( bool visibleAreaOnly = false, QgsRasterLayer::ContrastEnhancementLimits theLimits = QgsRasterLayer::ContrastEnhancementMinMax );
// actions for menus and toolbars -----------------

View File

@ -435,7 +435,15 @@ void QgsRasterDataProvider::initStatistics( QgsRasterBandStats &theStatistics,
theStatistics.bandNumber = theBandNo;
theStatistics.statsGathered = theStats;
QgsRectangle myExtent = theExtent.isEmpty() ? extent() : theExtent;
QgsRectangle myExtent;
if ( theExtent.isEmpty() )
{
myExtent = extent();
}
else
{
myExtent = extent().intersect( &theExtent );
}
theStatistics.extent = myExtent;
if ( theSampleSize > 0 )
@ -674,7 +682,15 @@ void QgsRasterDataProvider::initHistogram( QgsRasterHistogram &theHistogram,
}
}
QgsRectangle myExtent = theExtent.isEmpty() ? extent() : theExtent;
QgsRectangle myExtent;
if ( theExtent.isEmpty() )
{
myExtent = extent();
}
else
{
myExtent = extent().intersect( &theExtent );
}
theHistogram.extent = myExtent;
if ( theSampleSize > 0 )

View File

@ -96,6 +96,10 @@ typedef bool isvalidrasterfilename_t( QString const & theFileNameQString, QStrin
// doubles can take for the current system. (Yes, 20 was arbitrary.)
#define TINY_VALUE std::numeric_limits<double>::epsilon() * 20
const double QgsRasterLayer::CUMULATIVE_CUT_LOWER = 0.02;
const double QgsRasterLayer::CUMULATIVE_CUT_UPPER = 0.98;
const double QgsRasterLayer::SAMPLE_SIZE = 250000;
QgsRasterLayer::QgsRasterLayer()
: QgsMapLayer( RasterLayer )
, QSTRING_NOT_SET( "Not Set" )
@ -1845,71 +1849,91 @@ void QgsRasterLayer::setColorShadingAlgorithm( QString )
void QgsRasterLayer::setContrastEnhancementAlgorithm( QgsContrastEnhancement::ContrastEnhancementAlgorithm theAlgorithm, bool theGenerateLookupTableFlag )
{
setContrastEnhancementAlgorithm( theAlgorithm, ContrastEnhancementMinMax, QgsRectangle(), SAMPLE_SIZE, theGenerateLookupTableFlag );
}
void QgsRasterLayer::setContrastEnhancementAlgorithm( QgsContrastEnhancement::ContrastEnhancementAlgorithm theAlgorithm, ContrastEnhancementLimits theLimits, QgsRectangle theExtent, int theSampleSize, bool theGenerateLookupTableFlag )
{
QgsDebugMsg( QString( "theAlgorithm = %1 theLimits = %2 theExtent.isEmpty() = %3" ).arg( theAlgorithm ).arg( theLimits ).arg( theExtent.isEmpty() ) );
if ( !mPipe.renderer() || !mDataProvider )
{
return;
}
QList<int> myBands;
QList<QgsContrastEnhancement*> myEnhancements;
QgsSingleBandGrayRenderer* myGrayRenderer = 0;
QgsMultiBandColorRenderer* myMultiBandRenderer = 0;
QString rendererType = mPipe.renderer()->type();
if ( rendererType == "singlebandgray" )
{
QgsSingleBandGrayRenderer* gr = dynamic_cast<QgsSingleBandGrayRenderer*>( mPipe.renderer() );
if ( gr )
{
int grayBand = gr->grayBand();
if ( grayBand == -1 )
{
return;
}
QgsRasterDataProvider::DataType dataType = ( QgsRasterDataProvider::DataType )mDataProvider->dataType( grayBand );
QgsContrastEnhancement* ce = new QgsContrastEnhancement(( QgsContrastEnhancement::QgsRasterDataType )dataType );
ce->setContrastEnhancementAlgorithm( theAlgorithm, theGenerateLookupTableFlag );
ce->setMinimumValue( mDataProvider->minimumValue( grayBand ) );
ce->setMaximumValue( mDataProvider->maximumValue( grayBand ) );
gr->setContrastEnhancement( ce );
}
myGrayRenderer = dynamic_cast<QgsSingleBandGrayRenderer*>( mPipe.renderer() );
if ( !myGrayRenderer ) return;
myBands << myGrayRenderer->grayBand();
}
else if ( rendererType == "multibandcolor" )
{
QgsMultiBandColorRenderer* cr = dynamic_cast<QgsMultiBandColorRenderer*>( mPipe.renderer() );
if ( cr )
myMultiBandRenderer = dynamic_cast<QgsMultiBandColorRenderer*>( mPipe.renderer() );
if ( !myMultiBandRenderer ) return;
myBands << myMultiBandRenderer->redBand() << myMultiBandRenderer->greenBand() << myMultiBandRenderer->blueBand();
}
foreach( int myBand, myBands )
{
if ( myBand != -1 )
{
//red enhancement
int redBand = cr->redBand();
if ( redBand != -1 )
QgsRasterDataProvider::DataType myType = ( QgsRasterDataProvider::DataType )mDataProvider->dataType( myBand );
QgsContrastEnhancement* myEnhancement = new QgsContrastEnhancement(( QgsContrastEnhancement::QgsRasterDataType )myType );
myEnhancement->setContrastEnhancementAlgorithm( theAlgorithm, theGenerateLookupTableFlag );
double myMin = std::numeric_limits<double>::quiet_NaN();
double myMax = std::numeric_limits<double>::quiet_NaN();
if ( theLimits == ContrastEnhancementMinMax )
{
QgsRasterDataProvider::DataType redType = ( QgsRasterDataProvider::DataType )mDataProvider->dataType( redBand );
QgsContrastEnhancement* redEnhancement = new QgsContrastEnhancement(( QgsContrastEnhancement::QgsRasterDataType )redType );
redEnhancement->setContrastEnhancementAlgorithm( theAlgorithm, theGenerateLookupTableFlag );
redEnhancement->setMinimumValue( mDataProvider->minimumValue( redBand ) );
redEnhancement->setMaximumValue( mDataProvider->maximumValue( redBand ) );
cr->setRedContrastEnhancement( redEnhancement );
// minimumValue/maximumValue are not well defined (estimation) and will be removed
//myMin = mDataProvider->minimumValue( myBand );
//myMax = mDataProvider->maximumValue( myBand );
QgsRasterBandStats myRasterBandStats = mDataProvider->bandStatistics( myBand, QgsRasterBandStats::Min | QgsRasterBandStats::Max, theExtent, theSampleSize );
myMin = myRasterBandStats.minimumValue;
myMax = myRasterBandStats.maximumValue;
}
else if ( theLimits == ContrastEnhancementStdDev )
{
double myStdDev = 1; // make optional?
QgsRasterBandStats myRasterBandStats = mDataProvider->bandStatistics( myBand, QgsRasterBandStats::Mean | QgsRasterBandStats::StdDev, theExtent, theSampleSize );
myMin = myRasterBandStats.mean - ( myStdDev * myRasterBandStats.stdDev );
myMax = myRasterBandStats.mean + ( myStdDev * myRasterBandStats.stdDev );
}
else if ( theLimits == ContrastEnhancementCumulativeCut )
{
QSettings mySettings;
double myLower = mySettings.value( "/Raster/cumulativeCutLower", QString::number( CUMULATIVE_CUT_LOWER ) ).toDouble();
double myUpper = mySettings.value( "/Raster/cumulativeCutUpper", QString::number( CUMULATIVE_CUT_UPPER ) ).toDouble();
QgsDebugMsg( QString( "myLower = %1 myUpper = %2" ).arg( myLower ).arg( myUpper ) );
mDataProvider->cumulativeCut( myBand, myLower, myUpper, myMin, myMax, theExtent, theSampleSize );
}
//green enhancement
int greenBand = cr->greenBand();
if ( greenBand != -1 )
{
QgsRasterDataProvider::DataType greenType = ( QgsRasterDataProvider::DataType )mDataProvider->dataType( cr->greenBand() );
QgsContrastEnhancement* greenEnhancement = new QgsContrastEnhancement(( QgsContrastEnhancement::QgsRasterDataType )greenType );
greenEnhancement->setContrastEnhancementAlgorithm( theAlgorithm, theGenerateLookupTableFlag );
greenEnhancement->setMinimumValue( mDataProvider->minimumValue( greenBand ) );
greenEnhancement->setMaximumValue( mDataProvider->maximumValue( greenBand ) );
cr->setGreenContrastEnhancement( greenEnhancement );
}
//blue enhancement
int blueBand = cr->blueBand();
if ( blueBand != -1 )
{
QgsRasterDataProvider::DataType blueType = ( QgsRasterDataProvider::DataType )mDataProvider->dataType( cr->blueBand() );
QgsContrastEnhancement* blueEnhancement = new QgsContrastEnhancement(( QgsContrastEnhancement::QgsRasterDataType )blueType );
blueEnhancement->setContrastEnhancementAlgorithm( theAlgorithm, theGenerateLookupTableFlag );
blueEnhancement->setMinimumValue( mDataProvider->minimumValue( blueBand ) );
blueEnhancement->setMaximumValue( mDataProvider->maximumValue( blueBand ) );
cr->setBlueContrastEnhancement( blueEnhancement );
}
QgsDebugMsg( QString( "myBand = %1 myMin = %2 myMax = %3" ).arg( myBand ).arg( myMin ).arg( myMax ) );
myEnhancement->setMinimumValue( myMin );
myEnhancement->setMaximumValue( myMax );
myEnhancements.append( myEnhancement );
}
else
{
myEnhancements.append( 0 );
}
}
if ( rendererType == "singlebandgray" )
{
if ( myEnhancements.value( 0 ) ) myGrayRenderer->setContrastEnhancement( myEnhancements.value( 0 ) );
}
else if ( rendererType == "multibandcolor" )
{
if ( myEnhancements.value( 0 ) ) myMultiBandRenderer->setRedContrastEnhancement( myEnhancements.value( 0 ) );
if ( myEnhancements.value( 1 ) ) myMultiBandRenderer->setGreenContrastEnhancement( myEnhancements.value( 1 ) );
if ( myEnhancements.value( 2 ) ) myMultiBandRenderer->setBlueContrastEnhancement( myEnhancements.value( 2 ) );
}
}

View File

@ -174,6 +174,15 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
{
Q_OBJECT
public:
/** \brief Default cumulative cut lower limit */
static const double CUMULATIVE_CUT_LOWER;
/** \brief Default cumulative cut upper limit */
static const double CUMULATIVE_CUT_UPPER;
/** \brief Default sample size (number of pixels) for estimated statistics/histogram calculation */
static const double SAMPLE_SIZE;
/** \brief Constructor. Provider is not set. */
QgsRasterLayer();
@ -243,7 +252,15 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
Palette,
Multiband,
ColorLayer
} ;
};
/** \brief Contrast enhancement limits */
enum ContrastEnhancementLimits
{
ContrastEnhancementMinMax,
ContrastEnhancementStdDev,
ContrastEnhancementCumulativeCut
};
/** \brief A list containing on ContrastEnhancement object per raster band in this raster layer */
typedef QList<QgsContrastEnhancement> ContrastEnhancementList;
@ -548,10 +565,25 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
/** \brief Mutator for color shader algorithm */
Q_DECL_DEPRECATED void setColorShadingAlgorithm( QString theShaderAlgorithm );
/** \brief Mutator for contrast enhancement algorithm */
/** \brief Mutator for contrast enhancement algorithm using min/max */
// TODO: remove in 2.0, replaced by following
void setContrastEnhancementAlgorithm( QgsContrastEnhancement::ContrastEnhancementAlgorithm theAlgorithm,
bool theGenerateLookupTableFlag = true );
/** \brief Mutator for contrast enhancement algorithm
* @param theAlgorithm Contrast enhancement algorithm
* @param theLimits Limits
* @param theExtent Extent used to calculate limits, if empty, use full layer extent
* @param theSampleSize Size of data sample to calculate limits, if 0, use full resolution
* @param theGenerateLookupTableFlag Generate llokup table. */
void setContrastEnhancementAlgorithm( QgsContrastEnhancement::ContrastEnhancementAlgorithm theAlgorithm,
ContrastEnhancementLimits theLimits = ContrastEnhancementMinMax,
QgsRectangle theExtent = QgsRectangle(),
int theSampleSize = SAMPLE_SIZE,
bool theGenerateLookupTableFlag = true );
/** \brief Mutator for contrast enhancement algorithm */
void setContrastEnhancementAlgorithm( QString theAlgorithm, bool theGenerateLookupTableFlag = true );

View File

@ -22,6 +22,8 @@
#include "qgsrasterdataprovider.h"
#include <QPair>
#include "cpl_conv.h"
class QPainter;
class QgsMapToPixel;
class QgsRasterResampler;

View File

@ -70,7 +70,7 @@ void QgsRasterMinMaxWidget::on_mLoadPushButton_clicked()
}
else if ( mStdDevRadioButton->isChecked() )
{
QgsRasterBandStats myRasterBandStats = mLayer->dataProvider()->bandStatistics( myBand, QgsRasterBandStats::Mean, myExtent, mySampleSize );
QgsRasterBandStats myRasterBandStats = mLayer->dataProvider()->bandStatistics( myBand, QgsRasterBandStats::Mean | QgsRasterBandStats::StdDev, myExtent, mySampleSize );
double myStdDev = mStdDevSpinBox->value();
myMin = myRasterBandStats.mean - ( myStdDev * myRasterBandStats.stdDev );
myMax = myRasterBandStats.mean + ( myStdDev * myRasterBandStats.stdDev );

View File

@ -28,7 +28,6 @@
#include "sanewconnection.h"
#include "qgsquerybuilder.h"
#include "qgisapp.h"
#include "qgslogger.h"
#include "qgsapplication.h"
#include "qgscontexthelp.h"

View File

@ -17,7 +17,7 @@
<x>0</x>
<y>0</y>
<width>1052</width>
<height>26</height>
<height>21</height>
</rect>
</property>
<widget class="QMenu" name="mEditMenu">
@ -189,12 +189,6 @@
<addaction name="separator"/>
<addaction name="mActionShowPythonDialog"/>
</widget>
<widget class="QMenu" name="mRasterMenu">
<property name="title">
<string>&amp;Raster</string>
</property>
<addaction name="mActionShowRasterCalculator"/>
</widget>
<widget class="QMenu" name="mHelpMenu">
<property name="title">
<string>&amp;Help</string>
@ -220,6 +214,12 @@
<addaction name="mActionOptions"/>
<addaction name="mActionSnappingOptions"/>
</widget>
<widget class="QMenu" name="mRasterMenu">
<property name="title">
<string>&amp;Raster</string>
</property>
<addaction name="mActionShowRasterCalculator"/>
</widget>
<addaction name="mFileMenu"/>
<addaction name="mEditMenu"/>
<addaction name="mViewMenu"/>
@ -385,8 +385,10 @@
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="mActionFullHistogramStretch"/>
<addaction name="mActionLocalCumulativeCutStretch"/>
<addaction name="mActionFullCumulativeCutStretch"/>
<addaction name="mActionLocalHistogramStretch"/>
<addaction name="mActionFullHistogramStretch"/>
</widget>
<widget class="QToolBar" name="mLabelToolBar">
<property name="windowTitle">
@ -1748,6 +1750,30 @@ Shift thaws, Alt toggles, Ctl (Cmd) hides</string>
<string>New Blank Project</string>
</property>
</action>
<action name="mActionLocalCumulativeCutStretch">
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mActionLocalCumulativeCutStretch.png</normaloff>:/images/themes/default/mActionLocalCumulativeCutStretch.png</iconset>
</property>
<property name="text">
<string>Local Cumulative Cut Stretch</string>
</property>
<property name="toolTip">
<string>Local cumulative cut stretch using current extent, default limits and estimated values.</string>
</property>
</action>
<action name="mActionFullCumulativeCutStretch">
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mActionFullCumulativeCutStretch.png</normaloff>:/images/themes/default/mActionFullCumulativeCutStretch.png</iconset>
</property>
<property name="text">
<string>Full Dataset Cumulative Cut Stretch</string>
</property>
<property name="toolTip">
<string>Cumulative cut stretch using full dataset extent, default limits and estimated values.</string>
</property>
</action>
</widget>
<resources>
<include location="../../images/images.qrc"/>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 118 KiB