renable hsla filter as 'scale-hsla' - refs #1954

This commit is contained in:
Dane Springmeyer 2013-07-19 00:37:51 -04:00
parent 23c5b0f2f7
commit 0872061993
20 changed files with 64 additions and 70 deletions

View file

@ -10,6 +10,8 @@ For a complete change history, see the git log.
- Added `premultiplied` property on mapnik::image_32 / mapnik.Image to enable knowledge of premultiplied status of image buffer. - Added `premultiplied` property on mapnik::image_32 / mapnik.Image to enable knowledge of premultiplied status of image buffer.
- Added `scale-hsla` image-filter that allows scaling colors in HSL color space. RGB is converted to HSL (hue-saturation-lightness) and then each value (and the original alpha value) is stretched based on the specified scaling values. An example syntax is `scale-hsla(0,1,0,1,0,1,0,1)` which means no change because the full range will be kept (0 for lowest, 1 for highest). Other examples are: 1) `scale-hsla(0,0,0,1,0,1,0,1)` which would force all colors to be red in hue in the same way `scale-hsla(1,1,0,1,0,1,0,1)` would, 2) `scale-hsla(0,1,1,1,0,1,0,1)` which would cause all colors to become fully saturated, 3) `scale-hsla(0,1,1,1,0,1,.5,1)` which would force no colors to be any more transparent than half, and 4) `scale-hsla(0,1,1,1,0,1,0,.5)` which would force all colors to be at least half transparent. (#1954)
## 2.2.0 ## 2.2.0
Released June 3rd, 2013 Released June 3rd, 2013

View file

@ -483,9 +483,8 @@ void apply_filter(Src & src, colorize_alpha const& op)
} }
} }
/*
template <typename Src> template <typename Src>
void apply_filter(Src & src, hsla const& transform) void apply_filter(Src & src, scale_hsla const& transform)
{ {
using namespace boost::gil; using namespace boost::gil;
bool tinting = !transform.is_identity(); bool tinting = !transform.is_identity();
@ -504,16 +503,24 @@ void apply_filter(Src & src, hsla const& transform)
uint8_t & g = get_color(src_it[x], green_t()); uint8_t & g = get_color(src_it[x], green_t());
uint8_t & b = get_color(src_it[x], blue_t()); uint8_t & b = get_color(src_it[x], blue_t());
uint8_t & a = get_color(src_it[x], alpha_t()); uint8_t & a = get_color(src_it[x], alpha_t());
double a2 = a/255.0; double a2 = static_cast<double>(a)/255.0;
double a1 = a2; double a1 = a2;
bool alpha_modified = false;
if (set_alpha && a2 > 0.01) if (set_alpha && a2 > 0.01)
{ {
a2 = transform.a0 + (a2 * (transform.a1 - transform.a0)); a2 = transform.a0 + (a2 * (transform.a1 - transform.a0));
if (a2 <= 0)
{
a = 0;
}
else
{
a = static_cast<unsigned>(std::floor((a2 * 255.0) +.5)); a = static_cast<unsigned>(std::floor((a2 * 255.0) +.5));
if (a > 255) a = 255; if (a > 255) a = 255;
if (a < 0) a = 0;
} }
if (tinting && a2 > 0.01) alpha_modified = true;
}
if (tinting && a > 1)
{ {
double h; double h;
double s; double s;
@ -534,12 +541,12 @@ void apply_filter(Src & src, hsla const& transform)
double h2 = transform.h0 + (h * (transform.h1 - transform.h0)); double h2 = transform.h0 + (h * (transform.h1 - transform.h0));
double s2 = transform.s0 + (s * (transform.s1 - transform.s0)); double s2 = transform.s0 + (s * (transform.s1 - transform.s0));
double l2 = transform.l0 + (l * (transform.l1 - transform.l0)); double l2 = transform.l0 + (l * (transform.l1 - transform.l0));
if (h2 > 1) { std::clog << "h2: " << h2 << "\n"; h2 = 1; } if (h2 > 1) { h2 = 1; }
else if (h2 < 0) { std::clog << "h2: " << h2 << "\n"; h2 = 0; } else if (h2 < 0) { h2 = 0; }
if (s2 > 1) { std::clog << "h2: " << h2 << "\n"; s2 = 1; } if (s2 > 1) { s2 = 1; }
else if (s2 < 0) { std::clog << "s2: " << s2 << "\n"; s2 = 0; } else if (s2 < 0) { s2 = 0; }
if (l2 > 1) { std::clog << "h2: " << h2 << "\n"; l2 = 1; } if (l2 > 1) { l2 = 1; }
else if (l2 < 0) { std::clog << "l2: " << l2 << "\n"; l2 = 0; } else if (l2 < 0) { l2 = 0; }
hsl2rgb(h2,s2,l2,r,g,b); hsl2rgb(h2,s2,l2,r,g,b);
// premultiply // premultiply
// we only work with premultiplied source, // we only work with premultiplied source,
@ -548,7 +555,7 @@ void apply_filter(Src & src, hsla const& transform)
g *= a2; g *= a2;
b *= a2; b *= a2;
} }
else else if (alpha_modified)
{ {
// demultiply // demultiply
if (a1 <= 0.0) if (a1 <= 0.0)
@ -573,7 +580,6 @@ void apply_filter(Src & src, hsla const& transform)
} }
} }
} }
*/
template <typename Src> template <typename Src>
void apply_filter(Src & src, gray const& op) void apply_filter(Src & src, gray const& op)

View file

@ -67,8 +67,8 @@ struct image_filter_grammar :
qi::rule<Iterator, ContType(), qi::ascii::space_type> start; qi::rule<Iterator, ContType(), qi::ascii::space_type> start;
qi::rule<Iterator, ContType(), qi::ascii::space_type> filter; qi::rule<Iterator, ContType(), qi::ascii::space_type> filter;
qi::rule<Iterator, qi::locals<int,int>, void(ContType&), qi::ascii::space_type> agg_blur_filter; qi::rule<Iterator, qi::locals<int,int>, void(ContType&), qi::ascii::space_type> agg_blur_filter;
//qi::rule<Iterator, qi::locals<double,double,double,double,double,double,double,double>, qi::rule<Iterator, qi::locals<double,double,double,double,double,double,double,double>,
// void(ContType&), qi::ascii::space_type> hsla_filter; void(ContType&), qi::ascii::space_type> scale_hsla_filter;
qi::rule<Iterator, qi::locals<mapnik::filter::colorize_alpha, mapnik::filter::color_stop>, void(ContType&), qi::ascii::space_type> colorize_alpha_filter; qi::rule<Iterator, qi::locals<mapnik::filter::colorize_alpha, mapnik::filter::color_stop>, void(ContType&), qi::ascii::space_type> colorize_alpha_filter;
qi::rule<Iterator, qi::ascii::space_type> no_args; qi::rule<Iterator, qi::ascii::space_type> no_args;
qi::uint_parser< unsigned, 10, 1, 3 > radius_; qi::uint_parser< unsigned, 10, 1, 3 > radius_;

View file

@ -28,7 +28,6 @@
#include <mapnik/color.hpp> #include <mapnik/color.hpp>
// boost // boost
#include <boost/variant.hpp> #include <boost/variant.hpp>
#include <boost/variant/variant_fwd.hpp>
// stl // stl
#include <vector> #include <vector>
#include <ostream> #include <ostream>
@ -54,10 +53,9 @@ struct agg_stack_blur
unsigned ry; unsigned ry;
}; };
/* struct scale_hsla
struct hsla
{ {
hsla(double _h0, double _h1, scale_hsla(double _h0, double _h1,
double _s0, double _s1, double _s0, double _s1,
double _l0, double _l1, double _l0, double _l1,
double _a0, double _a1) : double _a0, double _a1) :
@ -81,14 +79,6 @@ struct hsla
return (a0 == 0 && return (a0 == 0 &&
a1 == 1); a1 == 1);
} }
std::string to_string() const {
std::ostringstream s;
s << h0 << "x" << h1 << ";"
<< s0 << "x" << s1 << ";"
<< l0 << "x" << l1 << ";"
<< a0 << "x" << a1;
return s.str();
}
double h0; double h0;
double h1; double h1;
double s0; double s0;
@ -98,7 +88,6 @@ struct hsla
double a0; double a0;
double a1; double a1;
}; };
*/
struct color_stop struct color_stop
{ {
@ -124,7 +113,7 @@ typedef boost::variant<filter::blur,
filter::x_gradient, filter::x_gradient,
filter::y_gradient, filter::y_gradient,
filter::invert, filter::invert,
//filter::hsla, filter::scale_hsla,
filter::colorize_alpha> filter_type; filter::colorize_alpha> filter_type;
inline std::ostream& operator<< (std::ostream& os, blur) inline std::ostream& operator<< (std::ostream& os, blur)
@ -145,16 +134,14 @@ inline std::ostream& operator<< (std::ostream& os, agg_stack_blur const& filter)
return os; return os;
} }
/* inline std::ostream& operator<< (std::ostream& os, scale_hsla const& filter)
inline std::ostream& operator<< (std::ostream& os, hsla const& filter)
{ {
os << "hsla(" << filter.h0 << 'x' << filter.h1 << ':' os << "hsla-transform(" << filter.h0 << 'x' << filter.h1 << ':'
<< filter.s0 << 'x' << filter.s1 << ':' << filter.s0 << 'x' << filter.s1 << ':'
<< filter.l0 << 'x' << filter.l1 << ':' << filter.l0 << 'x' << filter.l1 << ':'
<< filter.a0 << 'x' << filter.a1 << ')'; << filter.a0 << 'x' << filter.a1 << ')';
return os; return os;
} }
*/
inline std::ostream& operator<< (std::ostream& os, emboss) inline std::ostream& operator<< (std::ostream& os, emboss)
{ {
@ -198,7 +185,27 @@ inline std::ostream& operator<< (std::ostream& os, invert)
return os; return os;
} }
inline std::ostream& operator<< (std::ostream& os, filter_type const& filter); template <typename Out>
struct to_string_visitor : boost::static_visitor<void>
{
to_string_visitor(Out & out)
: out_(out) {}
template <typename T>
void operator () (T const& filter_tag)
{
out_ << filter_tag;
}
Out & out_;
};
inline std::ostream& operator<< (std::ostream& os, filter_type const& filter)
{
to_string_visitor<std::ostream> visitor(os);
boost::apply_visitor(visitor, filter);
return os;
}
MAPNIK_DECL bool generate_image_filters(std::back_insert_iterator<std::string> & sink, std::vector<filter_type> const& v); MAPNIK_DECL bool generate_image_filters(std::back_insert_iterator<std::string> & sink, std::vector<filter_type> const& v);

View file

@ -88,8 +88,8 @@ image_filter_grammar<Iterator,ContType>::image_filter_grammar()
| |
agg_blur_filter(_val) agg_blur_filter(_val)
| |
//hsla_filter(_val) scale_hsla_filter(_val)
//| |
colorize_alpha_filter(_val) colorize_alpha_filter(_val)
; ;
@ -100,16 +100,14 @@ image_filter_grammar<Iterator,ContType>::image_filter_grammar()
[push_back(_r1,construct<mapnik::filter::agg_stack_blur>(_a,_b))] [push_back(_r1,construct<mapnik::filter::agg_stack_blur>(_a,_b))]
; ;
/* scale_hsla_filter = lit("scale-hsla")
hsla_filter = lit("hsla")
>> lit('(') >> lit('(')
>> double_[_a = _1] >> lit('x') >> double_[_b = _1] >> lit(';') >> double_[_a = _1] >> lit(',') >> double_[_b = _1] >> lit(',')
>> double_[_c = _1] >> lit('x') >> double_[_d = _1] >> lit(';') >> double_[_c = _1] >> lit(',') >> double_[_d = _1] >> lit(',')
>> double_[_e = _1] >> lit('x') >> double_[_f = _1] >> lit(';') >> double_[_e = _1] >> lit(',') >> double_[_f = _1] >> lit(',')
>> double_[_g = _1] >> lit('x') >> double_[_h = _1] >> lit(')') >> double_[_g = _1] >> lit(',') >> double_[_h = _1] >> lit(')')
[push_back(_r1, construct<mapnik::filter::hsla>(_a,_b,_c,_d,_e,_f,_g,_h))] [push_back(_r1, construct<mapnik::filter::scale_hsla>(_a,_b,_c,_d,_e,_f,_g,_h))]
; ;
*/
colorize_alpha_filter = lit("colorize-alpha")[_a = construct<mapnik::filter::colorize_alpha>()] colorize_alpha_filter = lit("colorize-alpha")[_a = construct<mapnik::filter::colorize_alpha>()]
>> lit('(') >> lit('(')

View file

@ -34,28 +34,6 @@ namespace mapnik {
namespace filter { namespace filter {
template <typename Out>
struct to_string_visitor : boost::static_visitor<void>
{
to_string_visitor(Out & out)
: out_(out) {}
template <typename T>
void operator () (T const& filter_tag)
{
out_ << filter_tag;
}
Out & out_;
};
inline std::ostream& operator<< (std::ostream& os, filter_type const& filter)
{
to_string_visitor<std::ostream> visitor(os);
boost::apply_visitor(visitor, filter);
return os;
}
bool generate_image_filters(std::back_insert_iterator<std::string>& sink, std::vector<filter_type> const& filters) bool generate_image_filters(std::back_insert_iterator<std::string>& sink, std::vector<filter_type> const& filters)
{ {
using boost::spirit::karma::stream; using boost::spirit::karma::stream;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View file

@ -1,6 +1,9 @@
<Map srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs" background-image="../../data/images/checker.jpg"> <Map srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs" background-image="../../data/images/checker.jpg">
<Style name="ellipse" image-filters="hsla(0x.5;.5x1;0x.5;0x1)"> <Style name="ellipse"
direct-image-filters=" scale-hsla(0,1,0,1,0,1,0,.5)"
image-filters="scale-hsla(.1,.9,.5,1,.5,1,.2,1)"
>
<Rule> <Rule>
<MarkersSymbolizer <MarkersSymbolizer
width="240" width="240"

View file

@ -102,7 +102,7 @@ files = {
'marker-on-line-spacing-eq-width-overlap': {'sizes':[(600,400)]}, 'marker-on-line-spacing-eq-width-overlap': {'sizes':[(600,400)]},
'marker_line_placement_on_points':{}, 'marker_line_placement_on_points':{},
'marker-with-background-image': {'sizes':[(600,400),(400,600),(257,256)]}, 'marker-with-background-image': {'sizes':[(600,400),(400,600),(257,256)]},
#'marker-with-background-image-and-hsla-transform': {'sizes':[(600,400),(400,600),(257,256)]}, 'marker-with-background-image-and-hsla-transform': {'sizes':[(600,400),(400,600),(257,256)]},
'marker-on-hex-grid': {'sizes':[(600,400),(400,600),(257,256)]}, 'marker-on-hex-grid': {'sizes':[(600,400),(400,600),(257,256)]},
'whole-centroid': {'sizes':[(600,400)], 'whole-centroid': {'sizes':[(600,400)],
'bbox': mapnik.Box2d(736908, 4390316, 2060771, 5942346)}, 'bbox': mapnik.Box2d(736908, 4390316, 2060771, 5942346)},