Skip to content

Instantly share code, notes, and snippets.

@mistic100
Last active October 27, 2021 08:47
Show Gist options
  • Save mistic100/9301c0eebaef047bfdc8 to your computer and use it in GitHub Desktop.
Save mistic100/9301c0eebaef047bfdc8 to your computer and use it in GitHub Desktop.
[PHP] Draw a rectangle with rounded corners
<?php
/**
* Draw a rectangle with rounded corners.
* @param ressource &$img An image resource
* @param int $x1 Upper left x coordinate
* @param int $y1 Upper left y coordinate
* @param int $x2 Bottom right x coordinate
* @param int $y2 Bottom right y coordinate
* @param int $r Corners radius
* @param int $color A color identifier created with imagecolorallocate()
* @return true
*/
function imageroundedrectangle(&$img, $x1, $y1, $x2, $y2, $r, $color)
{
$r = min($r, floor(min(($x2-$x1)/2, ($y2-$y1)/2)));
// top border
imageline($img, $x1+$r, $y1, $x2-$r, $y1, $color);
// right border
imageline($img, $x2, $y1+$r, $x2, $y2-$r, $color);
// bottom border
imageline($img, $x1+$r, $y2, $x2-$r, $y2, $color);
// left border
imageline($img, $x1, $y1+$r, $x1, $y2-$r, $color);
// top-left arc
imagearc($img, $x1+$r, $y1+$r, $r*2, $r*2, 180, 270, $color);
// top-right arc
imagearc($img, $x2-$r, $y1+$r, $r*2, $r*2, 270, 0, $color);
// bottom-right arc
imagearc($img, $x2-$r, $y2-$r, $r*2, $r*2, 0, 90, $color);
// bottom-left arc
imagearc($img, $x1+$r, $y2-$r, $r*2, $r*2, 90, 180, $color);
return true;
}
@ErikKalkoken
Copy link

works great. Thanks for sharing!

@charmstead
Copy link

charmstead commented Apr 19, 2019

Nice work. I made some additions incase you want a filled rounded corner rectangle.

<?php
function imageroundedrectangle(&$img, $x1, $y1, $x2, $y2, $r, $color)
{
    $r = min($r, floor(min(($x2 - $x1) / 2, ($y2 - $y1) / 2)));

    // top border
    imageline($img, $x1 + $r, $y1, $x2 - $r, $y1, $color);
    // right border
    imageline($img, $x2, $y1 + $r, $x2, $y2 - $r, $color);
    // bottom border
    imageline($img, $x1 + $r, $y2, $x2 - $r, $y2, $color);
    // left border
    imageline($img, $x1, $y1 + $r, $x1, $y2 - $r, $color);

    // top-left arc
    imagefilledarc($img, $x1 + $r, $y1 + $r, $r * 2, $r * 2, 180, 270, $color, IMG_ARC_PIE);
    imagefilledarc($img, $x1 + 1.5, $y1 + 1.5, 200, 150, 0, 90, $color, IMG_ARC_PIE);

    // top-right arc
    imagefilledarc($img, $x2 - $r, $y1 + $r, $r * 2, $r * 2, 270, 0, $color, IMG_ARC_PIE);
    imagefilledarc($img, $x2 - 0.5, $y1 + 1.5, 200, 150, 90, 180, $color, IMG_ARC_PIE);

    // bottom-right arc
    imagefilledarc($img, $x2 - $r, $y2 - $r, $r * 2, $r * 2, 0, 90, $color, IMG_ARC_PIE);
    imagefilledarc($img, $x2 - 0.5, $y2 - 0.5, 200, 150, 180, 270, $color, IMG_ARC_PIE);

    // bottom-left arc
    imagefilledarc($img, $x1 + $r, $y2 - $r, $r * 2, $r * 2, 0, 180, $color, IMG_ARC_PIE);
    imagefilledarc($img, $x1 + 1.5, $y2 - 0.5, 200, 150, 270, 360, $color, IMG_ARC_PIE);

    return true;
}

@LukeHaillay
Copy link

LukeHaillay commented Oct 2, 2019

cheamsteads function didn't work properly for me, revised if anyone wants to try this version

function imageroundedrectangle(&$img, $x1, $y1, $x2, $y2, $r, $color){
    $r = min($r, floor(min(($x2 - $x1) / 2, ($y2 - $y1) / 2)));
    // render corners
    imagefilledarc($img, $x1 + $r, $y1 + $r, $r * 2, $r * 2, 180, 270, $color, IMG_ARC_PIE);
    imagefilledarc($img, $x2 - $r, $y1 + $r, $r * 2, $r * 2, 270, 0, $color, IMG_ARC_PIE);
    imagefilledarc($img, $x2 - $r, $y2 - $r, $r * 2, $r * 2, 0, 90, $color, IMG_ARC_PIE);
    imagefilledarc($img, $x1 + $r, $y2 - $r, $r * 2, $r * 2, 0, 180, $color, IMG_ARC_PIE);
    // middle fill, left fill, right fill
    imagefilledrectangle($img, $x1+$r, $y1, $x2-$r, $y2, $color);
    imagefilledrectangle($img, $x1, $y1+$r, $x1+$r, $y2-$r, $color);
    imagefilledrectangle($img, $x2-$r, $y1+$r, $x2, $y2-$r, $color);
    return true;
}

Copy link

ghost commented May 9, 2020

I used the solution to make a filled rounded rectangle. It works very well, however if you want to make a semi transparent rounded rectangle then you need to have a +1 and -1 on the "// middle fill, left fill, right fill" otherwise the overlaps create a darkened line. None the less KUDOS for this solution(s).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment