Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

image-filters and alpha channel #1313

Closed
lightmare opened this Issue Jul 11, 2012 · 16 comments

Comments

Projects
None yet
4 participants
Contributor

lightmare commented Jul 11, 2012

Are they intended to work on semi-transparent layers (in the future)? If not, skip the rest.

I was playing with this map. Red halos (with transparent text) on the yellow street are on layer LA. All other street labels with halos, and also the green and blue dashes on streets, are in a single style SB on layer LB. Numbers are not involved, they're on yet another layer.
no filter

With image-filters="gray" added to SB, alpha goes away and LB covers the whole map.
gray filter

I patched the 'gray' filter to preserve alpha (basically r=g=b=rgb_to_luminance(r,g,b)), and got this. I can't explain how a label with fill="#00000099" halo-fill="#ffffff99" halo-radius="2" (on the yellow street) after passing through 'gray' filter comes out with green spots around it. Or how random black pixels appear around labels that only had solid white halo, but not those that had blue or green halo. Does anyone have an idea what's going on?
gray filter with alpha

Then I tried image-filters="blur". It probably doesn't account for alpha at all, so it uses the full color of even completely transparent neighborhood to compute the color of a pixel.
blur filter

Owner

springmeyer commented Jul 12, 2012

Yeah, @artemp will know more but image-filters only predictably work on rgb right now. However the odd colors you are getting at fringes look like overflows due to premultiplication being handled improperly somewhere.

A very small testcase would help.

Contributor

lightmare commented Jul 13, 2012

Thanks for the hint, I'll look into it next week. This weekend it's ICFPc :)

Owner

artemp commented Jul 13, 2012

@lightmare - have a nice one!

Contributor

lightmare commented Jul 18, 2012

I changed the gray filter to do nothing, like this:

diff --git a/include/mapnik/image_filter.hpp b/include/mapnik/image_filter.hpp
index 58fee01..e78de80 100644
--- a/include/mapnik/image_filter.hpp
+++ b/include/mapnik/image_filter.hpp
@@ -393,6 +393,8 @@ void apply_filter(Src & src, agg_stack_blur const& op)
 template <typename Src>
 void apply_filter(Src & src, gray)
 {
+    return;
+
     using namespace boost::gil;
     typedef pixel<channel_type<rgba8_view_t>::type, gray_layout_t> gray_pixel_t;

Here's a testcase with images.
outmap-with-noop-filter.png is rendered with no-op gray filter. If i remove the filter from the style (change image-filters="gray" to image-filters=""), the result is outmap-no-filter.png.

Somehow mere presence of the filter, although it doesn't do anything, causes green speckles around text. I looked at the source pixels inside gray filter, some of them had R=G=B=(A+1), which I believe were pre-multiplied white pixels. But with color components greater than A, demultiplication results in R`=(R_255/A)=((A+1)_255/A)>255, doesn't it?

Owner

artemp commented Jul 18, 2012

@lightmare thanks for the test case! most likely pre/de-multiplication is wrong. I'll have a look (hopefully tomorrow).

Owner

springmeyer commented Aug 3, 2012

marked as mustfix and assigned to 2.1 milestone since this seems important to fix before release.

@springmeyer springmeyer pushed a commit that referenced this issue Sep 1, 2012

Dane Springmeyer agg compositing: change src_over alpha to avoid pixel artifacts by re…
…ordering computations and add basic tests comparing src_over composting to normal agg alpha blending - closes #1452 - refs #1313, #1454, #1369
5e84ce0
Owner

springmeyer commented Sep 1, 2012

@lightmare - now that we've figure out that src_over was broken, I figure that explains some of the oddities you were seeing above, even after fixing the image-filters to account for alpha.

So, how about we start addressing image-filters one by one in terms of which work with premultiplied alpha (like agg-stack-blur does and needs no fixes) and which do not. And of those that do not, figure out which should handle alpha vs ignore alpha. Sounds like you have a good patch for grey. For others we could consider demultiplying before and premultiply again after, but I worry about rounding errors...

Contributor

lightmare commented Sep 1, 2012

@springmeyer Yes I should have a patch for gray somewhere. But when playing with it, I also refactored much of image filters header, so it'll probably take some time to clean up.

As for demultiply-apply-premultiply, that won't work for filters that look at neighboring pixels - there each pixel should be weighted by it's alpha, so that transparent pixels don't affect the result at edges. I'm willing to do that, I only didn't start previously because it will come at a price (more ops/pixel) and I wasn't sure whether that's acceptable (for it will slow down even when all pixels are opaque).

image-filters + scaling bug:
tc_nodata
Style:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Map>
<Map background-color="#faf9f5" srs="+proj=merc +datum=WGS84 +over" maximum-extent="9717000, 6254000, 9742000, 6262000" minimum-version="2.2.0">
  <Style name="hillshade" image-filters="sharpen">
    <Rule>
      <MaxScaleDenominator>200000</MaxScaleDenominator>
      <RasterSymbolizer scaling="quadric"/>
    </Rule>
  </Style>

  <Layer name="hillshade_zl11" status="on" srs="+proj=merc +datum=WGS84 +over" maxzoom="200000">
    <StyleName>hillshade</StyleName>
    <Datasource>
      <Parameter name='type'>gdal</Parameter>
      <Parameter name='file'>hs_zl11_23_48.tif</Parameter>
    </Datasource>
  </Layer>
</Map>

(A perfect) testcase

Owner

springmeyer commented Jun 12, 2014

yes, thanks for the testcase: this shows what we know: that the 'sharpen' filter does not play right with alpha and needs fixed.

@artemp artemp self-assigned this Jun 12, 2014

Owner

artemp commented Jun 18, 2014

@Andrey-VI - I'm looking into this, meanwhile, you might want to try direct-image-filters

direct-image-filter-sharpen

...
<Style name="hillshade" direct-image-filters="sharpen">
...

Yes! direct-image-filters works well.
Thanks, @artemp!

Owner

artemp commented Jun 19, 2014

@springmeyer - you were right, image-filters should be applied in de-multiplied colour space.

fixed in master : 2fb3069

Owner

artemp commented Jun 19, 2014

@Andrey-VI - you can try using your original style with master ^

@artemp,
no I can't. #1818 should be closed before.

@springmeyer springmeyer added this to the Mapnik 2.3.0 milestone Jun 19, 2014

Owner

springmeyer commented Jun 19, 2014

fixed in 2.3.x and 3.x closing.

@springmeyer springmeyer added a commit to mapnik/node-mapnik that referenced this issue Jul 2, 2014

@springmeyer springmeyer update expected test - refs mapnik/mapnik#1313 4d50b5d
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment