php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #74664 Polyline produces closed polygon
Submitted: 2017-05-27 16:06 UTC Modified: 2017-06-15 15:27 UTC
From: lee dot traynor at skeptic dot de Assigned: danack (profile)
Status: Assigned Package: imagick (PECL)
PHP Version: 7.0.19 OS: Windows 10
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2017-05-27 16:06 UTC] lee dot traynor at skeptic dot de
Description:
------------
---
From manual page: http://www.php.net/imagickdraw.polyline
---
Under certain irregular conditions the ImagickDraw function polyline produces a closed polygon, identical to function polygon.

I have noticed that I can draw lines with stroke width of up to 2 pixels and they remain open, but on changing the stroke width to anything > 2 the line closes.

Test script:
---------------
// $pc is an array of several hundred coordinates of the form [['x'=>1, 'y'=>1], ['x'=>2, 'y'=>4]...]

$im = new Imagick ();
$im->newImage (1000, 1500, "white");
$draw = new ImagickDraw ();
$draw->setStrokeWidth (2);
$draw->polyline ($pc);
$im->drawImage ($draw); // OK

Changing the value in setStrokeWidth to > 2 closes the polygon

Workaround is to reverse the original array and append it to the end of the original array, i.e. to trace back over the polyline to avoid closing it.

$pc = array_merge ($pc, array_reverse ($pc)); // draws an open polyline


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-05-28 01:09 UTC] danack@php.net
Please can you say what version of ImageMagick you have installed.

Also please can you post an example array that shows this. It's going to be hard to investigate without a reproducible case.
 [2017-05-29 13:30 UTC] danack@php.net
-Status: Open +Status: Feedback
 [2017-05-29 13:30 UTC] danack@php.net
Forgot to set feedback status. 

No one will be able to investigate this without a reproduce case.
 [2017-06-11 04:22 UTC] pecl-dev at lists dot php dot net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Re-Opened". Thank you.
 [2017-06-12 09:44 UTC] danack@php.net
-Status: No Feedback +Status: Assigned -Assigned To: +Assigned To: danack
 [2017-06-12 09:44 UTC] danack@php.net
Lee - this does sound like a serious bug, but not one that can be fixed without a repro case.

Please can you take the time to make one?
 [2017-06-14 19:36 UTC] lee dot traynor at skeptic dot de
This has occurred as part of a larger project and I have been unable to isolate the code necessary to reproduce the result outside of the project. Currently, polyline seems to be behaving itself, but should this arise again, I will reopen the bug.

If this occurs, it would be nice if I could see what the draw object contains to see if I am possibly trying to draw the same polyline twice, thus joining end and start points (that is about the only logical error I can think of that I might be making). However, the object properties appear to be hidden.
 [2017-06-15 15:27 UTC] danack@php.net
> If this occurs, it would be nice if I could see what the draw object contains 

Extending the class to be able to log this type of thing, is usually better than relying on internal logging.

Here is an approximation of one way of doing that.


class ImagickDrawLogging extends ImagickDraw {

    static public $recordedCoordinates = [];

    public function polyline ( array $coordinates ) {
        self::$recordedCoordinates[] = $coordinates;
        parent::polyline($coordinates);
    }

    public static function logInfo() {
        
        if (count(self::$recordedCoordinates) == 0) {
            return;
        }
        
        $temp_file = tempnam(sys_get_temp_dir(), 'poly_debug');
        file_put_contents($temp_file, var_export(self::$recordedCoordinates, true));
    }
}


// Put this at the start of your program
$debug_imagick_draw = random_int(1, 100);
if ($debug_imagick_draw <= 3) {
    // only log 3% of requests
    class_alias('ImagickDrawLogging', 'ImagickDrawDebug');
}
else {
    class_alias('ImagickDraw', 'ImagickDrawDebug');
}


// Put this at the end of your program
\ImagickDrawLogging::logInfo();


And change ImagickDraw => ImagickDrawDebug for the place where you're going to be calling polyline.


That will record the ImagickDraw polyline calls for a small percentage of users. Obviously, if you're testing in dev, you could enable that for all requests.
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Sun Nov 19 01:31:42 2017 UTC