Jump to content

Imagick Draw a Pie Slice?


Axeia

Recommended Posts

If someone could tell me how to draw a pie slice using imagick I'd really appreciate it.

This is what my test case looks like:

<?php
$width =  200;
$height = 100;

$img = new Imagick();
$img->newImage( $width, $height, new ImagickPixel( 'orange' ) );

$draw = new ImagickDraw();
$draw->setStrokeColor( new ImagickPixel( 'black' ) );
$draw->setStrokeWidth( 2 );
$draw->setFillColor( new ImagickPixel( 'lime' ) );
$draw->pathEllipticArcAbsolute( $width/2, $height/2, 0, true, false, 0, 30  );
$img->drawImage( $draw );
$img->setImageFormat( "png" );

header( "Content-Type: image/png" );
echo $img;
?>

 

But it throws a

“Fatal error: Uncaught exception ‘ImagickException’ with message ‘Non-conforming drawing primitive definition `A100” in /srv/www/htdocs/fetish/index.php:556 Stack trace: #0 /srv/www/htdocs/fetish/index.php(556): Imagick->drawimage(Object(ImagickDraw)) #1 {main} thrown in /srv/www/htdocs/fetish/index.php on line 556″

Also tried creating a svg and converting that, but the converting process is too slow..

Link to comment
https://forums.phpfreaks.com/topic/152706-imagick-draw-a-pie-slice/
Share on other sites

677a1732407671.gifWell I made some progress, I got it to draw something.. and it even seems to be slightly arced, but I can't figure out how to make it actually round instead of angular.

(My previous problem was that all path function calls should be between a pathStart and pathClose call.. something I overlooked.)

 

If someone else wants to give it a go, the code is:

<?php
    function getPointOnCircumference( $widthOfCircle, $heightOfCircle, $degrees, $x = 0, $y = 0 )
    {
        return array( 
            'x' => $x + ($widthOfCircle/2)  * sin( deg2rad( $degrees ) ),
            'y' => $y + ($heightOfCircle/2) * cos( deg2rad( $degrees ) )
        );
    }

    $width  = 400;
    $height = 400;
    $x = $width / 2;
    $y = $height / 2;
    $im = new Imagick();
    $im->newImage( $width, $height, "black", "png" );

    $draw1 = new ImagickDraw();
    $draw1->setFillColor( 'lime' );
    $draw1->pathStart();
    for( $i = 0; $i < 360; $i+=30 )
    {
        $draw1->pathMoveToAbsolute( $x/2, $y/2 ); //Move 'pencil' to middle of image.
        $point = getPointOnCircumference( $width/2, $height/2, $i );
        $draw1->pathLineToRelative( $point['x'], $point['y'] );
    }	
    $draw1->pathClose();
    $im->DrawImage( $draw1 );

    $draw2 = new ImagickDraw();
    $draw2->setFillColor( 'orange' );
    $draw2->setStrokeColor( 'red' );
    $draw2->pathStart();
    for( $i = 0; $i < 360; $i+=30 )
    {
        $draw2->pathMoveToAbsolute( $x+$x/2, $y/2 ); //Move 'pencil' to middle of image.
        $point = getPointOnCircumference( $width/2, $height/2, $i );
        $draw2->pathLineToRelative( $point['x'], $point['y'] );
        $point = getPointOnCircumference( $width/2, $height/2, $i+30 );
        $draw2->pathLineToAbsolute( ($x+$x/2)+$point['x'], $y/2+$point['y'] );
    }   
    $draw2->pathClose();
    $im->DrawImage( $draw2 );

    $draw3 = new ImagickDraw();
    $draw3->setFillColor( 'pink' );
    $draw3->setStrokeColor( 'yellow' );
    $draw3->pathStart();
    for( $i = 0; $i < 360; $i+=30 )
    {
        $draw3->pathMoveToAbsolute( $x/2, $y+$y/2 ); //Move 'pencil' to middle of image.
        $point = getPointOnCircumference( $width/2, $height/2, $i );
        $draw3->pathLineToRelative( $point['x'], $point['y'] );
        $point = getPointOnCircumference( $width/2, $height/2, $i+30 );
        $draw3->pathEllipticArcAbsolute( $width/2, $height/2, 0, false, false, $x/2+$point['x'], ($y+$y/2)+$point['y'] );
    }   
    $draw3->pathClose();
    $im->DrawImage( $draw3 );	

    header( "Content-Type: image/png" );
    echo $im;
?>

$draw3 is the bottomleft image.. which is almost what I'm after.

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.