[FEATURE][raster] transparency support for paletted renderer

This commit is contained in:
nirvn 2016-12-10 10:30:48 +07:00
parent 287ed2d39c
commit f02e4ad98f
7 changed files with 57 additions and 20 deletions

View File

@ -1246,6 +1246,11 @@ has improved sort capabilities including the ability to set custom sort values f
and for forcing certain items to always sort on top.
QgsPalettedRasterRenderer {#qgis_api_break_3_0_QgsPalettedRasterRenderer}
-------------------------
- The rgbArray() method was made private
QgsPalLabeling {#qgis_api_break_3_0_QgsPalLabeling}
--------------

View File

@ -17,11 +17,6 @@ class QgsPalettedRasterRenderer : QgsRasterRenderer
/** Returns copy of color array (caller takes ownership)*/
QColor* colors() const /Factory/;
/** Returns copy of rgb array (caller takes ownership)
@note not available in python bindings
*/
// QRgb* rgbArray() const;
/** Return optional category label
* @note added in 2.1 */
QString label( int idx ) const;

View File

@ -18,6 +18,7 @@
#include "qgspalettedrasterrenderer.h"
#include "qgsrastertransparency.h"
#include "qgsrasterviewport.h"
#include <QColor>
#include <QDomDocument>
#include <QDomElement>
@ -31,7 +32,7 @@ QgsPalettedRasterRenderer::QgsPalettedRasterRenderer( QgsRasterInterface* input,
mColors = new QRgb[nColors];
for ( int i = 0; i < nColors; ++i )
{
mColors[i] = colorArray[i].rgba();
mColors[i] = qPremultiply( colorArray[i].rgba() );
}
delete[] colorArray;
}
@ -95,7 +96,9 @@ QgsRasterRenderer* QgsPalettedRasterRenderer::create( const QDomElement& elem, Q
QgsDebugMsgLevel( entryElem.attribute( "color", "#000000" ), 4 );
if ( value >= 0 && value < nColors )
{
colors[value] = QColor( entryElem.attribute( QStringLiteral( "color" ), QStringLiteral( "#000000" ) ) ).rgba();
QColor color = QColor( entryElem.attribute( QStringLiteral( "color" ), QStringLiteral( "#000000" ) ) );
color.setAlpha( entryElem.attribute( QStringLiteral( "alpha" ), QStringLiteral( "255" ) ).toInt() );
colors[value] = qPremultiply( color.rgba() );
QString label = entryElem.attribute( QStringLiteral( "label" ) );
if ( !label.isEmpty() )
{
@ -123,7 +126,7 @@ QColor* QgsPalettedRasterRenderer::colors() const
QColor* colorArray = new QColor[ mNColors ];
for ( int i = 0; i < mNColors; ++i )
{
colorArray[i] = QColor( mColors[i] );
colorArray[i] = QColor::fromRgba( qUnpremultiply( mColors[i] ) );
}
return colorArray;
}
@ -172,6 +175,7 @@ QgsRasterBlock * QgsPalettedRasterRenderer::block( int bandNo, QgsRectangle con
//rendering is faster without considering user-defined transparency
bool hasTransparency = usesTransparency();
QgsRasterBlock *alphaBlock = nullptr;
if ( mAlphaBand > 0 && mAlphaBand != mBand )
@ -211,6 +215,7 @@ QgsRasterBlock * QgsPalettedRasterRenderer::block( int bandNo, QgsRectangle con
continue;
}
int val = ( int ) inputBlock->value( i );
if ( !hasTransparency )
{
outputData[i] = mColors[val];
@ -226,8 +231,9 @@ QgsRasterBlock * QgsPalettedRasterRenderer::block( int bandNo, QgsRectangle con
{
currentOpacity *= alphaBlock->value( i ) / 255.0;
}
QColor currentColor = QColor( mColors[val] );
outputData[i] = qRgba( currentOpacity * currentColor.red(), currentOpacity * currentColor.green(), currentOpacity * currentColor.blue(), currentOpacity * 255 );
QRgb c = mColors[val];
outputData[i] = qRgba( currentOpacity * qRed( c ), currentOpacity * qGreen( c ), currentOpacity * qBlue( c ), currentOpacity * qAlpha( c ) );
}
}
@ -254,9 +260,11 @@ void QgsPalettedRasterRenderer::writeXml( QDomDocument& doc, QDomElement& parent
QDomElement colorPaletteElem = doc.createElement( QStringLiteral( "colorPalette" ) );
for ( int i = 0; i < mNColors; ++i )
{
QColor color = QColor::fromRgba( qUnpremultiply( mColors[i] ) );
QDomElement colorElem = doc.createElement( QStringLiteral( "paletteEntry" ) );
colorElem.setAttribute( QStringLiteral( "value" ), i );
colorElem.setAttribute( QStringLiteral( "color" ), QColor( mColors[i] ).name() );
colorElem.setAttribute( QStringLiteral( "color" ), color.name() );
colorElem.setAttribute( QStringLiteral( "alpha" ), color.alpha() );
if ( !label( i ).isEmpty() )
{
colorElem.setAttribute( QStringLiteral( "label" ), label( i ) );
@ -273,7 +281,7 @@ void QgsPalettedRasterRenderer::legendSymbologyItems( QList< QPair< QString, QCo
for ( int i = 0; i < mNColors; ++i )
{
QString lab = label( i ).isEmpty() ? QString::number( i ) : label( i );
symbolItems.push_back( qMakePair( lab, QColor( mColors[i] ) ) );
symbolItems.push_back( qMakePair( lab, QColor::fromRgba( qUnpremultiply( mColors[i] ) ) ) );
}
}

View File

@ -31,6 +31,7 @@ class QDomElement;
class CORE_EXPORT QgsPalettedRasterRenderer: public QgsRasterRenderer
{
public:
//! Renderer owns color array
QgsPalettedRasterRenderer( QgsRasterInterface* input, int bandNumber, QColor* colorArray, int nColors, const QVector<QString>& labels = QVector<QString>() );
QgsPalettedRasterRenderer( QgsRasterInterface* input, int bandNumber, QRgb* colorArray, int nColors, const QVector<QString>& labels = QVector<QString>() );
@ -45,11 +46,6 @@ class CORE_EXPORT QgsPalettedRasterRenderer: public QgsRasterRenderer
//! Returns copy of color array (caller takes ownership)
QColor* colors() const;
/** Returns copy of rgb array (caller takes ownership)
@note not available in python bindings
*/
QRgb* rgbArray() const;
/** Return optional category label
* @note added in 2.1 */
QString label( int idx ) const { return mLabels.value( idx ); }
@ -65,8 +61,13 @@ class CORE_EXPORT QgsPalettedRasterRenderer: public QgsRasterRenderer
QList<int> usesBands() const override;
private:
/** Returns copy of premultiplied rgb array (caller takes ownership)
*/
QRgb* rgbArray() const;
int mBand;
//! Color array
//! Premultiplied color array
QRgb* mColors;
//! Number of colors
int mNColors;

View File

@ -31,6 +31,7 @@ QgsPalettedRendererWidget::QgsPalettedRendererWidget( QgsRasterLayer* layer, con
contextMenu = new QMenu( tr( "Options" ), this );
contextMenu->addAction( tr( "Change color" ), this, SLOT( changeColor() ) );
contextMenu->addAction( tr( "Change transparency" ), this, SLOT( changeTransparency() ) );
mTreeWidget->setColumnWidth( ColorColumn, 50 );
mTreeWidget->setContextMenuPolicy( Qt::CustomContextMenu );
@ -87,7 +88,7 @@ void QgsPalettedRendererWidget::on_mTreeWidget_itemDoubleClicked( QTreeWidgetIte
if ( column == ColorColumn && item ) //change item color
{
item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
QColor c = QgsColorDialog::getColor( item->background( column ).color(), nullptr );
QColor c = QgsColorDialog::getColor( item->background( column ).color(), this, QStringLiteral( "Change color" ), true );
if ( c.isValid() )
{
item->setBackground( column, QBrush( c ) );
@ -167,3 +168,29 @@ void QgsPalettedRendererWidget::changeColor()
emit widgetChanged();
}
}
void QgsPalettedRendererWidget::changeTransparency()
{
QList<QTreeWidgetItem *> itemList;
itemList = mTreeWidget->selectedItems();
if ( itemList.isEmpty() )
{
return;
}
QTreeWidgetItem* firstItem = itemList.first();
bool ok;
double oldTransparency = ( firstItem->background( ColorColumn ).color().alpha() / 255.0 ) * 100.0;
double transparency = QInputDialog::getDouble( this, tr( "Transparency" ), tr( "Change color transparency [%]" ), oldTransparency, 0.0, 100.0, 0, &ok );
if ( ok )
{
int newTransparency = transparency / 100 * 255;
Q_FOREACH ( QTreeWidgetItem *item, itemList )
{
QColor newColor = item->background( ColorColumn ).color();
newColor.setAlpha( newTransparency );
item->setBackground( ColorColumn, QBrush( newColor ) );
}
emit widgetChanged();
}
}

View File

@ -56,6 +56,7 @@ class GUI_EXPORT QgsPalettedRendererWidget: public QgsRasterRendererWidget, priv
void on_mTreeWidget_itemDoubleClicked( QTreeWidgetItem * item, int column );
void on_mTreeWidget_itemChanged( QTreeWidgetItem * item, int column );
void changeColor();
void changeTransparency();
};
#endif // QGSPALETTEDRENDERERWIDGET_H

View File

@ -982,7 +982,7 @@ void QgsSingleBandPseudoColorRendererWidget::changeTransparency()
bool ok;
double oldTransparency = firstItem->background( ColorColumn ).color().alpha() / 255 * 100;
double transparency = QInputDialog::getDouble( this, tr( "Transparency" ), tr( "Change symbol transparency [%]" ), oldTransparency, 0.0, 100.0, 0, &ok );
double transparency = QInputDialog::getDouble( this, tr( "Transparency" ), tr( "Change color transparency [%]" ), oldTransparency, 0.0, 100.0, 0, &ok );
if ( ok )
{
int newTransparency = transparency / 100 * 255;