Skip Menu |

This queue is for tickets about the Imager CPAN distribution.

Report information
The Basics
Id: 71309
Status: resolved
Priority: 40/
Queue: Imager

People
Owner: Nobody in particular
Requestors: Ralf.Neubauer [...] wido.bv.aok.de
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.85
Fixed in: 0.86



Subject: polygons don't fit
Date: Wed, 28 Sep 2011 15:52:23 +0200
To: <bug-Imager [...] rt.cpan.org>
From: "Neubauer, Ralf" <Ralf.Neubauer [...] wido.bv.aok.de>
Hi. Distribution name and version: Imager-0.85 Perl version: v5.12.4 -- Binary build 1205 [294981] provided by ActiveState Operating System vendor and version: WinXP After building the very useful Imager module myself (because the ActiveState PPMs are buggy and e.g. don't support PNG and JPEG) I still get an effect that I first discovered some years ago with older (ActiveState and trouchelle distributed) Versions of Imager and perl: #! /usr/bin/perl use warnings; use strict; use Imager; my $img = new Imager(xsize => 100, ysize => 100, channels => 1); my $white = Imager::Color->new(255, 255, 255); my $black = Imager::Color->new(0, 0, 0); $img->box(color => $white, filled => 1, xmin => 0, ymin => 0, xmax => 99, ymax => 99); $img->polygon(color => $black, points => [[0,0], [0,99], [99,99]]); $img->polygon(color => $black, points => [[0,0], [99,99], [99,0]]); $img->write(file => 'polygonmatch.bmp') There is a fine grey line from (0,0) to (99,99). If I draw a shaded triangulation, e.g. 3D shaded boxes, I don't get a nice shaded image, but there are these lines between the triangles. Example: use Imager::Fountain; use Imager::Fill; my $cells = 10; my $xcell = 100; my $ycell = 150; $img = new Imager(xsize => $xcell*$cells, ysize => $ycell*$cells, channels => 3); my @color = map Imager::Color->new(map int rand 256, 0..2), 0..2; my $fountain = Imager::Fountain->simple (positions => [0, 0.1, 0.3, 0.7, 0.9, 1.0], colors => [@color[0, 1, 2, 2, 3, 0]]); for my $x (0..99) { for my $y (0..99) { my $tl = [$xcell*$x, $ycell*$y]; my $tr = [$xcell*$x+$xcell-1, $ycell*$y]; my $bl = [$xcell*$x, $ycell*$y+$ycell-1]; my $br = [$xcell*$x+$xcell-1, $ycell*$y+$ycell-1]; my $center = [$xcell*$x+int(($xcell-1)/2), $ycell*$y+int(($ycell-1)/2)]; my $fill_top_bottom = Imager::Fill->new(fountain => 'linear', segments => $fountain, xa => $tl->[0], ya => $tl->[1], xb => $bl->[0], yb => $bl->[1], ); my $fill_left_right = Imager::Fill->new(fountain => 'linear', segments => $fountain, xa => $tl->[0], ya => $tl->[1], xb => $tr->[0], yb => $tr->[1], ); $img->polygon(fill => $fill_top_bottom, points => [$br, $center, $bl]); $img->polygon(fill => $fill_top_bottom, points => [$tl, $center, $tr]); $img->polygon(fill => $fill_left_right, points => [$bl, $center, $tl]); $img->polygon(fill => $fill_left_right, points => [$tr, $center, $br]); } } $img->write(file => 'polygonmatch2.bmp'); The easiest fix would be an option for non-antialiased polygons. I tried hiding the artefacts behind lines: for my $xincr (-1,0,1) { $img->line(color => $color, aa => 0, x1 => $bl->[0]+$xincr, y1 => $bl->[1], x2 => $tr->[0]+$xincr, y2 => $tr->[1]); $img->line(color => $color, aa => 0, x1 => $br->[0]+$xincr, y1 => $br->[1], x2 => $tl->[0]+$xincr, y2 => $tl->[1]); } but that doesn't catch all pixels -- and is still the wrong color anyways. Ralf
On Wed Sep 28 09:53:00 2011, Ralf.Neubauer@wido.bv.aok.de wrote: Show quoted text
> After building the very useful Imager module myself (because the > ActiveState PPMs are buggy and e.g. don't support PNG and JPEG) I still > get an effect that I first discovered some years ago with older > (ActiveState and trouchelle distributed) Versions of Imager and perl: >
... Show quoted text
> There is a fine grey line from (0,0) to (99,99). If I draw a shaded > triangulation, e.g. 3D shaded boxes, I don't get a nice shaded image, > but there are these lines between the triangles. Example:
From looking at your code and the results I think you're encoutering two different problems: a) for your first sample, you're encountering a limitation in anti-aliasing, where two different operations have 50% coverage on the same pixels, producing 75% coverage instead of the mathematically expected coverage of 100%. As you say this could be fixed if Imager provided a non-AA polygon function. b) your second sample illustrates what seems to be a real bug in drawing anti-aliased polygons, and I've tracked it down. As a workaround for b) supply a combine of "normal" when creating the fill: my $fill_top_bottom = Imager::Fill->new(fountain => 'linear', segments => $fountain, xa => $tl->[0], ya => $tl->[1], xb => $bl->[0], yb => $bl->[1], combine => "normal", ); my $fill_left_right = Imager::Fill->new(fountain => 'linear', segments => $fountain, xa => $tl->[0], ya => $tl->[1], xb => $tr->[0], yb => $tr->[1], combine => "normal", ); To avoid a) for your tiles, you can fill the entire box with your top to bottom fill, then fill in the sides with the side fills: $img->polygon(fill => $fill_top_bottom,points => [$br, $tr, $tl, $bl]); $img->polygon(fill => $fill_left_right, points => [$bl, $center,$tl]); $img->polygon(fill => $fill_left_right, points => [$tr, $center,$br]); Your code does have a couple of small bugs: 1) when you initialize $fountain, you reference @color index 3, which you haven't initialized. 2) you fill 100 tiles in each dimension, while you only have 10. I'll look at a fix for b) for the next release of Imager. The anti-aliased polygons will need to wait a bit longer. Tony
On Wed Sep 28 09:53:00 2011, Ralf.Neubauer@wido.bv.aok.de wrote: Show quoted text
> > After building the very useful Imager module myself (because the > ActiveState PPMs are buggy and e.g. don't support PNG and JPEG) I still > get an effect that I first discovered some years ago with older > (ActiveState and trouchelle distributed) Versions of Imager and perl:
... Show quoted text
> > The easiest fix would be an option for non-antialiased polygons. > > I tried hiding the artefacts behind lines: > > for my $xincr (-1,0,1) { > $img->line(color => $color, aa => 0, > x1 => $bl->[0]+$xincr, y1 => $bl->[1], > x2 => $tr->[0]+$xincr, y2 => $tr->[1]); > $img->line(color => $color, aa => 0, > x1 => $br->[0]+$xincr, y1 => $br->[1], > x2 => $tl->[0]+$xincr, y2 => $tl->[1]); > } > > but that doesn't catch all pixels -- and is still the wrong color > anyways.
I've fixed the black border bug described here for Imager 0.86. Thanks, Tony