diff --git a/resources/function_help/json/color_grayscale_average b/resources/function_help/json/color_grayscale_average new file mode 100644 index 00000000000..2bcad6bfe31 --- /dev/null +++ b/resources/function_help/json/color_grayscale_average @@ -0,0 +1,9 @@ +{ + "name": "color_grayscale_average", + "type": "function", + "description": "Applies a grayscale filter and returns a string representation from a provided color.", + "arguments": [ + {"arg":"color", "description":"a color string"} + ], + "examples": [ { "expression":"color_grayscale_average('255,100,50')", "returns":"127,127,127,255"}] +} diff --git a/resources/function_help/json/color_mix_rgb b/resources/function_help/json/color_mix_rgb new file mode 100644 index 00000000000..61eb296e537 --- /dev/null +++ b/resources/function_help/json/color_mix_rgb @@ -0,0 +1,11 @@ +{ + "name": "color_mix_rgb", + "type": "function", + "description": "Returns a string representing a color mixing the reg, green, blue, and alpha values of two provided colors based on a given ratio.", + "arguments": [ + {"arg":"color1", "description":"a color string"}, + {"arg":"color2", "description":"a color string"}, + {"arg":"ratio", "description":"a ratio"} + ], + "examples": [ { "expression":"color_mix_rgb('0,0,0','255,255,255',0.5)", "returns":"127,127,127,255"}] +} diff --git a/src/core/expression/qgsexpressionfunction.cpp b/src/core/expression/qgsexpressionfunction.cpp index a79239f7e2c..745be763bdf 100644 --- a/src/core/expression/qgsexpressionfunction.cpp +++ b/src/core/expression/qgsexpressionfunction.cpp @@ -2998,6 +2998,41 @@ static QVariant fcnFormatDate( const QVariantList &values, const QgsExpressionCo return dt.toString( format ); } +static QVariant fcnColorGrayscaleAverage( const QVariantList &values, const QgsExpressionContext *, QgsExpression *, const QgsExpressionNodeFunction * ) +{ + QColor color = QgsSymbolLayerUtils::decodeColor( values.at( 0 ).toString() ); + int avg = ( color.red() + color.green() + color.blue() ) / 3; + int alpha = color.alpha(); + + color.setRgb( avg, avg, avg, alpha ); + + return QgsSymbolLayerUtils::encodeColor( color ); +} + +static QVariant fcnColorMixRgb( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * ) +{ + QColor color1 = QgsSymbolLayerUtils::decodeColor( values.at( 0 ).toString() ); + QColor color2 = QgsSymbolLayerUtils::decodeColor( values.at( 1 ).toString() ); + double ratio = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent ); + if ( ratio > 1 ) + { + ratio = 1; + } + else if ( ratio < 0 ) + { + ratio = 0; + } + + int red = color1.red() * ( 1 - ratio ) + color2.red() * ratio; + int green = color1.green() * ( 1 - ratio ) + color2.green() * ratio; + int blue = color1.blue() * ( 1 - ratio ) + color2.blue() * ratio; + int alpha = color1.alpha() * ( 1 - ratio ) + color2.alpha() * ratio; + + QColor newColor( red, green, blue, alpha ); + + return QgsSymbolLayerUtils::encodeColor( newColor ); +} + static QVariant fcnColorRgb( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * ) { int red = QgsExpressionUtils::getIntValue( values.at( 0 ), parent ); @@ -4098,6 +4133,8 @@ const QList &QgsExpression::Functions() << new QgsStaticExpressionFunction( QStringLiteral( "format" ), -1, fcnFormatString, QStringLiteral( "String" ) ) << new QgsStaticExpressionFunction( QStringLiteral( "format_number" ), 2, fcnFormatNumber, QStringLiteral( "String" ) ) << new QgsStaticExpressionFunction( QStringLiteral( "format_date" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "date" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "format" ) ), fcnFormatDate, QStringList() << QStringLiteral( "String" ) << QStringLiteral( "Date and Time" ) ) + << new QgsStaticExpressionFunction( QStringLiteral( "color_grayscale_average" ), 1, fcnColorGrayscaleAverage, QStringLiteral( "Color" ) ) + << new QgsStaticExpressionFunction( QStringLiteral( "color_mix_rgb" ), 3, fcnColorMixRgb, QStringLiteral( "Color" ) ) << new QgsStaticExpressionFunction( QStringLiteral( "color_rgb" ), 3, fcnColorRgb, QStringLiteral( "Color" ) ) << new QgsStaticExpressionFunction( QStringLiteral( "color_rgba" ), 4, fncColorRgba, QStringLiteral( "Color" ) ) << new QgsStaticExpressionFunction( QStringLiteral( "ramp_color" ), 2, fcnRampColor, QStringLiteral( "Color" ) ) diff --git a/tests/src/core/testqgsexpression.cpp b/tests/src/core/testqgsexpression.cpp index 37c0d5799d5..0d1c476aba7 100644 --- a/tests/src/core/testqgsexpression.cpp +++ b/tests/src/core/testqgsexpression.cpp @@ -1109,6 +1109,8 @@ class TestQgsExpression: public QObject QTest::newRow( "color hsva" ) << "color_hsva(40,100,100,200)" << false << QVariant( "255,170,0,200" ); QTest::newRow( "color cmyk" ) << "color_cmyk(100,50,33,10)" << false << QVariant( "0,115,154" ); QTest::newRow( "color cmyka" ) << "color_cmyka(50,25,90,60,200)" << false << QVariant( "51,76,10,200" ); + QTest::newRow( "color grayscale average" ) << "color_grayscale_average('255,100,50')" << false << QVariant( "135,135,135,255" ); + QTest::newRow( "color mix rgb" ) << "color_mix_rgb('0,0,0,100','255,255,255',0.5)" << false << QVariant( "127,127,127,177" ); QTest::newRow( "color part bad color" ) << "color_part('notacolor','red')" << true << QVariant(); QTest::newRow( "color part bad part" ) << "color_part(color_rgb(255,127,0),'bad')" << true << QVariant();