QGIS API Documentation  3.4.15-Madeira (e83d02e274)
qgsmultibandcolorrenderer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmultibandcolorrenderer.cpp
3  -----------------------------
4  begin : December 2011
5  copyright : (C) 2011 by Marco Hugentobler
6  email : marco at sourcepole dot ch
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
19 #include "qgscontrastenhancement.h"
20 #include "qgsrastertransparency.h"
21 #include "qgsrasterviewport.h"
22 
23 #include <QDomDocument>
24 #include <QDomElement>
25 #include <QImage>
26 #include <QSet>
27 
28 QgsMultiBandColorRenderer::QgsMultiBandColorRenderer( QgsRasterInterface *input, int redBand, int greenBand, int blueBand,
29  QgsContrastEnhancement *redEnhancement,
30  QgsContrastEnhancement *greenEnhancement,
31  QgsContrastEnhancement *blueEnhancement )
32  : QgsRasterRenderer( input, QStringLiteral( "multibandcolor" ) )
33  , mRedBand( redBand )
34  , mGreenBand( greenBand )
35  , mBlueBand( blueBand )
36  , mRedContrastEnhancement( redEnhancement )
37  , mGreenContrastEnhancement( greenEnhancement )
38  , mBlueContrastEnhancement( blueEnhancement )
39 {
40 }
41 
43 {
44  delete mRedContrastEnhancement;
45  delete mGreenContrastEnhancement;
46  delete mBlueContrastEnhancement;
47 }
48 
50 {
51  QgsMultiBandColorRenderer *renderer = new QgsMultiBandColorRenderer( nullptr, mRedBand, mGreenBand, mBlueBand );
52  renderer->copyCommonProperties( this );
53 
54  if ( mRedContrastEnhancement )
55  {
56  renderer->setRedContrastEnhancement( new QgsContrastEnhancement( *mRedContrastEnhancement ) );
57  }
58  if ( mGreenContrastEnhancement )
59  {
60  renderer->setGreenContrastEnhancement( new QgsContrastEnhancement( *mGreenContrastEnhancement ) );
61  }
62  if ( mBlueContrastEnhancement )
63  {
64  renderer->setBlueContrastEnhancement( new QgsContrastEnhancement( *mBlueContrastEnhancement ) );
65  }
66 
67  return renderer;
68 }
69 
71 {
72  delete mRedContrastEnhancement;
73  mRedContrastEnhancement = ce;
74 }
75 
77 {
78  delete mGreenContrastEnhancement;
79  mGreenContrastEnhancement = ce;
80 }
81 
83 {
84  delete mBlueContrastEnhancement;
85  mBlueContrastEnhancement = ce;
86 }
87 
89 {
90  if ( elem.isNull() )
91  {
92  return nullptr;
93  }
94 
95  //red band, green band, blue band
96  int redBand = elem.attribute( QStringLiteral( "redBand" ), QStringLiteral( "-1" ) ).toInt();
97  int greenBand = elem.attribute( QStringLiteral( "greenBand" ), QStringLiteral( "-1" ) ).toInt();
98  int blueBand = elem.attribute( QStringLiteral( "blueBand" ), QStringLiteral( "-1" ) ).toInt();
99 
100  //contrast enhancements
102  QDomElement redContrastElem = elem.firstChildElement( QStringLiteral( "redContrastEnhancement" ) );
103  if ( !redContrastElem.isNull() )
104  {
105  redContrastEnhancement = new QgsContrastEnhancement( ( Qgis::DataType )(
106  input->dataType( redBand ) ) );
107  redContrastEnhancement->readXml( redContrastElem );
108  }
109 
111  QDomElement greenContrastElem = elem.firstChildElement( QStringLiteral( "greenContrastEnhancement" ) );
112  if ( !greenContrastElem.isNull() )
113  {
114  greenContrastEnhancement = new QgsContrastEnhancement( ( Qgis::DataType )(
115  input->dataType( greenBand ) ) );
116  greenContrastEnhancement->readXml( greenContrastElem );
117  }
118 
120  QDomElement blueContrastElem = elem.firstChildElement( QStringLiteral( "blueContrastEnhancement" ) );
121  if ( !blueContrastElem.isNull() )
122  {
123  blueContrastEnhancement = new QgsContrastEnhancement( ( Qgis::DataType )(
124  input->dataType( blueBand ) ) );
125  blueContrastEnhancement->readXml( blueContrastElem );
126  }
127 
128  QgsRasterRenderer *r = new QgsMultiBandColorRenderer( input, redBand, greenBand, blueBand, redContrastEnhancement,
129  greenContrastEnhancement, blueContrastEnhancement );
130  r->readXml( elem );
131  return r;
132 }
133 
134 QgsRasterBlock *QgsMultiBandColorRenderer::block( int bandNo, QgsRectangle const &extent, int width, int height, QgsRasterBlockFeedback *feedback )
135 {
136  Q_UNUSED( bandNo );
137  std::unique_ptr< QgsRasterBlock > outputBlock( new QgsRasterBlock() );
138  if ( !mInput )
139  {
140  return outputBlock.release();
141  }
142 
143  //In some (common) cases, we can simplify the drawing loop considerably and save render time
144  bool fastDraw = ( !usesTransparency()
145  && mRedBand > 0 && mGreenBand > 0 && mBlueBand > 0
146  && mAlphaBand < 1 );
147 
148  QSet<int> bands;
149  if ( mRedBand > 0 )
150  {
151  bands << mRedBand;
152  }
153  if ( mGreenBand > 0 )
154  {
155  bands << mGreenBand;
156  }
157  if ( mBlueBand > 0 )
158  {
159  bands << mBlueBand;
160  }
161  if ( bands.empty() )
162  {
163  // no need to draw anything if no band is set
164  // TODO:: we should probably return default color block
165  return outputBlock.release();
166  }
167 
168  if ( mAlphaBand > 0 )
169  {
170  bands << mAlphaBand;
171  }
172 
173  QMap<int, QgsRasterBlock *> bandBlocks;
174  QgsRasterBlock *defaultPointer = nullptr;
175  QSet<int>::const_iterator bandIt = bands.constBegin();
176  for ( ; bandIt != bands.constEnd(); ++bandIt )
177  {
178  bandBlocks.insert( *bandIt, defaultPointer );
179  }
180 
181  QgsRasterBlock *redBlock = nullptr;
182  QgsRasterBlock *greenBlock = nullptr;
183  QgsRasterBlock *blueBlock = nullptr;
184  QgsRasterBlock *alphaBlock = nullptr;
185 
186  bandIt = bands.constBegin();
187  for ( ; bandIt != bands.constEnd(); ++bandIt )
188  {
189  bandBlocks[*bandIt] = mInput->block( *bandIt, extent, width, height, feedback );
190  if ( !bandBlocks[*bandIt] )
191  {
192  // We should free the alloced mem from block().
193  QgsDebugMsg( QStringLiteral( "No input band" ) );
194  --bandIt;
195  for ( ; bandIt != bands.constBegin(); --bandIt )
196  {
197  delete bandBlocks[*bandIt];
198  }
199  return outputBlock.release();
200  }
201  }
202 
203  if ( mRedBand > 0 )
204  {
205  redBlock = bandBlocks[mRedBand];
206  }
207  if ( mGreenBand > 0 )
208  {
209  greenBlock = bandBlocks[mGreenBand];
210  }
211  if ( mBlueBand > 0 )
212  {
213  blueBlock = bandBlocks[mBlueBand];
214  }
215  if ( mAlphaBand > 0 )
216  {
217  alphaBlock = bandBlocks[mAlphaBand];
218  }
219 
220  if ( !outputBlock->reset( Qgis::ARGB32_Premultiplied, width, height ) )
221  {
222  for ( int i = 0; i < bandBlocks.size(); i++ )
223  {
224  delete bandBlocks.value( i );
225  }
226  return outputBlock.release();
227  }
228 
229  QRgb *outputBlockColorData = outputBlock->colorData();
230 
231  // faster data access to data for the common case that input data are coming from RGB image with 8-bit bands
232  bool hasByteRgb = ( redBlock && greenBlock && blueBlock && redBlock->dataType() == Qgis::Byte && greenBlock->dataType() == Qgis::Byte && blueBlock->dataType() == Qgis::Byte );
233  const quint8 *redData = nullptr, *greenData = nullptr, *blueData = nullptr;
234  if ( hasByteRgb )
235  {
236  redData = redBlock->byteData();
237  greenData = greenBlock->byteData();
238  blueData = blueBlock->byteData();
239  }
240 
241  QRgb myDefaultColor = NODATA_COLOR;
242 
243  if ( fastDraw )
244  {
245  // By default RGB raster layers have contrast enhancement assigned and normally that requires us to take the slow
246  // route that applies the enhancement. However if the algorithm type is "no enhancement" and all input bands are byte-sized,
247  // no transform would be applied to the input values and we can take the fast route.
248  bool hasEnhancement;
249  if ( hasByteRgb )
250  {
251  hasEnhancement =
252  ( mRedContrastEnhancement && mRedContrastEnhancement->contrastEnhancementAlgorithm() != QgsContrastEnhancement::NoEnhancement ) ||
253  ( mGreenContrastEnhancement && mGreenContrastEnhancement->contrastEnhancementAlgorithm() != QgsContrastEnhancement::NoEnhancement ) ||
254  ( mBlueContrastEnhancement && mBlueContrastEnhancement->contrastEnhancementAlgorithm() != QgsContrastEnhancement::NoEnhancement );
255  }
256  else
257  {
258  hasEnhancement = mRedContrastEnhancement || mGreenContrastEnhancement || mBlueContrastEnhancement;
259  }
260  if ( hasEnhancement )
261  fastDraw = false;
262  }
263 
264  qgssize count = ( qgssize )width * height;
265  for ( qgssize i = 0; i < count; i++ )
266  {
267  if ( fastDraw ) //fast rendering if no transparency, stretching, color inversion, etc.
268  {
269  if ( redBlock->isNoData( i ) ||
270  greenBlock->isNoData( i ) ||
271  blueBlock->isNoData( i ) )
272  {
273  outputBlock->setColor( i, myDefaultColor );
274  }
275  else
276  {
277  if ( hasByteRgb )
278  {
279  outputBlockColorData[i] = qRgb( redData[i], greenData[i], blueData[i] );
280  }
281  else
282  {
283  int redVal = static_cast<int>( redBlock->value( i ) );
284  int greenVal = static_cast<int>( greenBlock->value( i ) );
285  int blueVal = static_cast<int>( blueBlock->value( i ) );
286  outputBlockColorData[i] = qRgb( redVal, greenVal, blueVal );
287  }
288  }
289  continue;
290  }
291 
292  bool isNoData = false;
293  double redVal = 0;
294  double greenVal = 0;
295  double blueVal = 0;
296  if ( mRedBand > 0 )
297  {
298  redVal = redBlock->value( i );
299  if ( redBlock->isNoData( i ) ) isNoData = true;
300  }
301  if ( !isNoData && mGreenBand > 0 )
302  {
303  greenVal = greenBlock->value( i );
304  if ( greenBlock->isNoData( i ) ) isNoData = true;
305  }
306  if ( !isNoData && mBlueBand > 0 )
307  {
308  blueVal = blueBlock->value( i );
309  if ( blueBlock->isNoData( i ) ) isNoData = true;
310  }
311  if ( isNoData )
312  {
313  outputBlock->setColor( i, myDefaultColor );
314  continue;
315  }
316 
317  //apply default color if red, green or blue not in displayable range
318  if ( ( mRedContrastEnhancement && !mRedContrastEnhancement->isValueInDisplayableRange( redVal ) )
319  || ( mGreenContrastEnhancement && !mGreenContrastEnhancement->isValueInDisplayableRange( redVal ) )
320  || ( mBlueContrastEnhancement && !mBlueContrastEnhancement->isValueInDisplayableRange( redVal ) ) )
321  {
322  outputBlock->setColor( i, myDefaultColor );
323  continue;
324  }
325 
326  //stretch color values
327  if ( mRedContrastEnhancement )
328  {
329  redVal = mRedContrastEnhancement->enhanceContrast( redVal );
330  }
331  if ( mGreenContrastEnhancement )
332  {
333  greenVal = mGreenContrastEnhancement->enhanceContrast( greenVal );
334  }
335  if ( mBlueContrastEnhancement )
336  {
337  blueVal = mBlueContrastEnhancement->enhanceContrast( blueVal );
338  }
339 
340  //opacity
341  double currentOpacity = mOpacity;
342  if ( mRasterTransparency )
343  {
344  currentOpacity = mRasterTransparency->alphaValue( redVal, greenVal, blueVal, mOpacity * 255 ) / 255.0;
345  }
346  if ( mAlphaBand > 0 )
347  {
348  currentOpacity *= alphaBlock->value( i ) / 255.0;
349  }
350 
351  if ( qgsDoubleNear( currentOpacity, 1.0 ) )
352  {
353  outputBlock->setColor( i, qRgba( redVal, greenVal, blueVal, 255 ) );
354  }
355  else
356  {
357  outputBlock->setColor( i, qRgba( currentOpacity * redVal, currentOpacity * greenVal, currentOpacity * blueVal, currentOpacity * 255 ) );
358  }
359  }
360 
361  //delete input blocks
362  QMap<int, QgsRasterBlock *>::const_iterator bandDelIt = bandBlocks.constBegin();
363  for ( ; bandDelIt != bandBlocks.constEnd(); ++bandDelIt )
364  {
365  delete bandDelIt.value();
366  }
367 
368  return outputBlock.release();
369 }
370 
371 void QgsMultiBandColorRenderer::writeXml( QDomDocument &doc, QDomElement &parentElem ) const
372 {
373  if ( parentElem.isNull() )
374  {
375  return;
376  }
377 
378  QDomElement rasterRendererElem = doc.createElement( QStringLiteral( "rasterrenderer" ) );
379  _writeXml( doc, rasterRendererElem );
380  rasterRendererElem.setAttribute( QStringLiteral( "redBand" ), mRedBand );
381  rasterRendererElem.setAttribute( QStringLiteral( "greenBand" ), mGreenBand );
382  rasterRendererElem.setAttribute( QStringLiteral( "blueBand" ), mBlueBand );
383 
384  //contrast enhancement
385  if ( mRedContrastEnhancement )
386  {
387  QDomElement redContrastElem = doc.createElement( QStringLiteral( "redContrastEnhancement" ) );
388  mRedContrastEnhancement->writeXml( doc, redContrastElem );
389  rasterRendererElem.appendChild( redContrastElem );
390  }
391  if ( mGreenContrastEnhancement )
392  {
393  QDomElement greenContrastElem = doc.createElement( QStringLiteral( "greenContrastEnhancement" ) );
394  mGreenContrastEnhancement->writeXml( doc, greenContrastElem );
395  rasterRendererElem.appendChild( greenContrastElem );
396  }
397  if ( mBlueContrastEnhancement )
398  {
399  QDomElement blueContrastElem = doc.createElement( QStringLiteral( "blueContrastEnhancement" ) );
400  mBlueContrastEnhancement->writeXml( doc, blueContrastElem );
401  rasterRendererElem.appendChild( blueContrastElem );
402  }
403  parentElem.appendChild( rasterRendererElem );
404 }
405 
407 {
408  QList<int> bandList;
409  if ( mRedBand != -1 )
410  {
411  bandList << mRedBand;
412  }
413  if ( mGreenBand != -1 )
414  {
415  bandList << mGreenBand;
416  }
417  if ( mBlueBand != -1 )
418  {
419  bandList << mBlueBand;
420  }
421  return bandList;
422 }
423 
424 void QgsMultiBandColorRenderer::toSld( QDomDocument &doc, QDomElement &element, const QgsStringMap &props ) const
425 {
426  QgsStringMap newProps = props;
427 
428  // create base structure
429  QgsRasterRenderer::toSld( doc, element, props );
430 
431 
432 #if 0
433  // TODO: the following jumped code is necessary to avoid to export channelSelection in
434  // case it's set as default value. The drawback is that it's necessary to calc band
435  // statistics that can be really slow depending on dataProvider and rastr localtion.
436  // this is the reason this part of code is commented and the channelSelection is
437  // always exported.
438  //
439  // before to export check if the band combination and contrast setting are the
440  // default ones to avoid to export this tags
441  bool isDefaultCombination = true;
442  QList<int> defaultBandCombination( { 1, 2, 3 } );
443 
444  isDefaultCombination = isDefaultCombination && ( usesBands() == defaultBandCombination );
445  isDefaultCombination = isDefaultCombination && (
449  );
450  // compute raster statistics (slow) only if true the previous conditions
451  if ( isDefaultCombination )
452  {
454  isDefaultCombination = isDefaultCombination && (
455  ( mRedContrastEnhancement->minimumValue() == statRed.minimumValue &&
456  mRedContrastEnhancement->maximumValue() == statRed.maximumValue )
457  );
458  }
459  if ( isDefaultCombination )
460  {
462  isDefaultCombination = isDefaultCombination && (
463  ( mGreenContrastEnhancement->minimumValue() == statGreen.minimumValue &&
464  mGreenContrastEnhancement->maximumValue() == statGreen.maximumValue )
465  );
466  }
467  if ( isDefaultCombination )
468  {
470  isDefaultCombination = isDefaultCombination && (
471  ( mBlueContrastEnhancement->minimumValue() == statBlue.minimumValue &&
472  mBlueContrastEnhancement->maximumValue() == statBlue.maximumValue )
473  );
474  }
475  if ( isDefaultCombination ):
476  return
477 #endif
478 
479  // look for RasterSymbolizer tag
480  QDomNodeList elements = element.elementsByTagName( QStringLiteral( "sld:RasterSymbolizer" ) );
481  if ( elements.size() == 0 )
482  return;
483 
484  // there SHOULD be only one
485  QDomElement rasterSymbolizerElem = elements.at( 0 ).toElement();
486 
487  // add Channel Selection tags
488  // Need to insert channelSelection in the correct sequence as in SLD standard e.g.
489  // after opacity or geometry or as first element after sld:RasterSymbolizer
490  QDomElement channelSelectionElem = doc.createElement( QStringLiteral( "sld:ChannelSelection" ) );
491  elements = rasterSymbolizerElem.elementsByTagName( QStringLiteral( "sld:Opacity" ) );
492  if ( elements.size() != 0 )
493  {
494  rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
495  }
496  else
497  {
498  elements = rasterSymbolizerElem.elementsByTagName( QStringLiteral( "sld:Geometry" ) );
499  if ( elements.size() != 0 )
500  {
501  rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
502  }
503  else
504  {
505  rasterSymbolizerElem.insertBefore( channelSelectionElem, rasterSymbolizerElem.firstChild() );
506  }
507  }
508 
509  // for each mapped band
510  static QStringList tags { QStringLiteral( "sld:RedChannel" ), QStringLiteral( "sld:GreenChannel" ), QStringLiteral( "sld:BlueChannel" ) };
511 
512  QList<QgsContrastEnhancement *> contrastEnhancements;
513  contrastEnhancements.append( mRedContrastEnhancement );
514  contrastEnhancements.append( mGreenContrastEnhancement );
515  contrastEnhancements.append( mBlueContrastEnhancement );
516 
517  QList<int> bands = usesBands();
518  QList<int>::const_iterator bandIt = bands.constBegin();
519  for ( int tagCounter = 0 ; bandIt != bands.constEnd(); ++bandIt, ++tagCounter )
520  {
521  if ( *bandIt < 0 )
522  continue;
523 
524  QDomElement channelElem = doc.createElement( tags[ tagCounter ] );
525  channelSelectionElem.appendChild( channelElem );
526 
527  // set band
528  QDomElement sourceChannelNameElem = doc.createElement( QStringLiteral( "sld:SourceChannelName" ) );
529  sourceChannelNameElem.appendChild( doc.createTextNode( QString::number( *bandIt ) ) );
530  channelElem.appendChild( sourceChannelNameElem );
531 
532  // set ContrastEnhancement for each band
533  // NO ContrastEnhancement parameter for the entire bands is managed e.g.
534  // because min/max values can vary depending on band.
535  if ( contrastEnhancements[ tagCounter ] )
536  {
537  QDomElement contrastEnhancementElem = doc.createElement( QStringLiteral( "sld:ContrastEnhancement" ) );
538  contrastEnhancements[ tagCounter ]->toSld( doc, contrastEnhancementElem );
539  channelElem.appendChild( contrastEnhancementElem );
540  }
541  }
542 }
int alphaValue(double value, int globalTransparency=255) const
Returns the transparency value for a single value pixel.
A rectangle specified with double values.
Definition: qgsrectangle.h:40
Qgis::DataType dataType() const
Returns data type.
static QgsRasterRenderer * create(const QDomElement &elem, QgsRasterInterface *input)
void writeXml(QDomDocument &doc, QDomElement &parentElem) const
const QgsContrastEnhancement * greenContrastEnhancement() const
void writeXml(QDomDocument &doc, QDomElement &parentElem) const override
Write base class members to xml.
ContrastEnhancementAlgorithm contrastEnhancementAlgorithm() const
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:278
DataType
Raster data types.
Definition: qgis.h:92
double maximumValue
The maximum cell value in the raster band.
virtual QgsRasterInterface * input() const
Current input.
const QgsContrastEnhancement * redContrastEnhancement() const
virtual Qgis::DataType dataType(int bandNo) const =0
Returns data type for the band specified by number.
QgsMultiBandColorRenderer * clone() const override
Clone itself, create deep copy.
QMap< QString, QString > QgsStringMap
Definition: qgis.h:577
void setGreenContrastEnhancement(QgsContrastEnhancement *ce)
Takes ownership.
QList< int > usesBands() const override
Returns a list of band numbers used by the renderer.
QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr) override
Read block of data using given extent and size.
bool usesTransparency() const
QgsRasterTransparency * mRasterTransparency
Raster transparency per color or value. Overwrites global alpha value.
static const QRgb NODATA_COLOR
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
Definition: qgis.h:107
virtual void toSld(QDomDocument &doc, QDomElement &element, const QgsStringMap &props=QgsStringMap()) const
Used from subclasses to create SLD Rule elements following SLD v1.0 specs.
The RasterBandStats struct is a container for statistics about a single raster band.
Raster data container.
void setRedContrastEnhancement(QgsContrastEnhancement *ce)
Takes ownership.
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.
double value(int row, int column) const
Read a single value if type of block is numeric.
void copyCommonProperties(const QgsRasterRenderer *other, bool copyMinMaxOrigin=true)
Copies common properties like opacity / transparency data from other renderer.
bool isValueInDisplayableRange(double value)
Returns true if a pixel value is in displayable range, false if pixel is outside of range (i...
void readXml(const QDomElement &elem)
const quint8 * byteData() const
Gives direct access to the raster block data.
double minimumValue() const
Returns the minimum value for the contrast enhancement range.
int mAlphaBand
Read alpha value from band.
void readXml(const QDomElement &rendererElem) override
Sets base class members from xml. Usually called from create() methods of subclasses.
Base class for processing filters like renderers, reprojector, resampler etc.
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...
Definition: qgis.h:586
const QgsContrastEnhancement * blueContrastEnhancement() const
void toSld(QDomDocument &doc, QDomElement &element, const QgsStringMap &props=QgsStringMap()) const override
Used from subclasses to create SLD Rule elements following SLD v1.0 specs.
virtual QgsRasterBandStats bandStatistics(int bandNo, int stats=QgsRasterBandStats::All, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, QgsRasterBlockFeedback *feedback=nullptr)
Returns the band statistics.
virtual QgsRectangle extent() const
Gets the extent of the interface.
double maximumValue() const
Returns the maximum value for the contrast enhancement range.
void setBlueContrastEnhancement(QgsContrastEnhancement *ce)
Takes ownership.
double minimumValue
The minimum cell value in the raster band.
Renderer for multiband images with the color components.
bool isNoData(int row, int column) const
Check if value at position is no data.
double mOpacity
Global alpha value (0-1)
Manipulates raster pixel values so that they enhanceContrast or clip into a specified numerical range...
QgsMultiBandColorRenderer(QgsRasterInterface *input, int redBand, int greenBand, int blueBand, QgsContrastEnhancement *redEnhancement=nullptr, QgsContrastEnhancement *greenEnhancement=nullptr, QgsContrastEnhancement *blueEnhancement=nullptr)
QgsRasterInterface * mInput
void _writeXml(QDomDocument &doc, QDomElement &rasterRendererElem) const
Write upper class info into rasterrenderer element (called by writeXml method of subclasses) ...
Feedback object tailored for raster block reading.
Raster renderer pipe that applies colors to a raster.
Eight bit unsigned integer (quint8)
Definition: qgis.h:95
int enhanceContrast(double value)
Applies the contrast enhancement to a value.