Rounded corners using PHP and the GD library

Why GD library?

I needed to add rounded corners to some pictures and didn’t want to modify the source files in Photoshop (I think it’s a bad idea to modify original pictures if the effect can be added dynamically).

First, I thought CSS would do the trick. But after finding some tutorials on the web (some also use Javascript), I realized that to get it working in most web browsers, it doesn’t seem that easy, and it generally means that you have to create wrapping DIVs.

That’s when I decided to use the GD library, which I had found very useful in other projects. I’m not saying that this solution is perfect or better that others, but it has worked very well for me, and I hope it will be useful to some of you as well.

Advantages of this solution:

  • Flexible: You can chose which corner(s) to round as well as the radius
  • Cross-browser: Since the rounded corners are applied server-side, there’s no need for CSS or Javascript support
  • Clean: no wrapping DIVs
  • The entire image can be rotated and still have rounded corners.

Known limitations:

  • Depending on your rounded corner image, a black border might be shown when using a radius different from the one in that rounded corner image, because of some transparency issues in the GD library. Thus, use a corner image with the correct size, if possible.
  • The src attribute must point to the function file, so you have to change the IMG tags in your code, for the pictures that need to have rounded corners.

PHP Code

<?php
/*
Description: Add rounded corners to an image with PHP and the GD library
Author: Michaël Niessen (2009)
Website: http://AssemblySys.com

If you find this script useful, you can show your
appreciation by getting Michaël a cup of coffee ;)
https://ko-fi.com/assemblysys

As long as this notice (including author name and details) is included and
UNALTERED, this code can be used and distributed freely.
*/
$image_file = $_GET['src'];
$corner_radius = isset($_GET['radius']) ? $_GET['radius'] : 20; // The default corner radius is set to 20px
$angle = isset($_GET['angle']) ? $_GET['angle'] : 0; // The default angle is set to 0º
$topleft = (isset($_GET['topleft']) and $_GET['topleft'] == "no") ? false : true; // Top-left rounded corner is shown by default
$bottomleft = (isset($_GET['bottomleft']) and $_GET['bottomleft'] == "no") ? false : true; // Bottom-left rounded corner is shown by default
$bottomright = (isset($_GET['bottomright']) and $_GET['bottomright'] == "no") ? false : true; // Bottom-right rounded corner is shown by default
$topright = (isset($_GET['topright']) and $_GET['topright'] == "no") ? false : true; // Top-right rounded corner is shown by default

$images_dir = 'images/';
$corner_source = imagecreatefrompng('images/rounded_corner.png');

$corner_width = imagesx($corner_source);  
$corner_height = imagesy($corner_source);  
$corner_resized = ImageCreateTrueColor($corner_radius, $corner_radius);
ImageCopyResampled($corner_resized, $corner_source, 0, 0, 0, 0, $corner_radius, $corner_radius, $corner_width, $corner_height);

$corner_width = imagesx($corner_resized);  
$corner_height = imagesy($corner_resized);  
$image = imagecreatetruecolor($corner_width, $corner_height);  
$image = imagecreatefromjpeg($images_dir . $image_file); // replace filename with $_GET['src'] 
$size = getimagesize($images_dir . $image_file); // replace filename with $_GET['src'] 
$white = ImageColorAllocate($image,255,255,255);
$black = ImageColorAllocate($image,0,0,0);

// Top-left corner
if ($topleft == true) {
    $dest_x = 0;  
    $dest_y = 0;  
    imagecolortransparent($corner_resized, $black); 
    imagecopymerge($image, $corner_resized, $dest_x, $dest_y, 0, 0, $corner_width, $corner_height, 100);
} 

// Bottom-left corner
if ($bottomleft == true) {
    $dest_x = 0;  
    $dest_y = $size[1] - $corner_height; 
    $rotated = imagerotate($corner_resized, 90, 0);
    imagecolortransparent($rotated, $black); 
    imagecopymerge($image, $rotated, $dest_x, $dest_y, 0, 0, $corner_width, $corner_height, 100);  
}

// Bottom-right corner
if ($bottomright == true) {
    $dest_x = $size[0] - $corner_width;  
    $dest_y = $size[1] - $corner_height;  
    $rotated = imagerotate($corner_resized, 180, 0);
    imagecolortransparent($rotated, $black); 
    imagecopymerge($image, $rotated, $dest_x, $dest_y, 0, 0, $corner_width, $corner_height, 100);  
}

// Top-right corner
if ($topright == true) {
    $dest_x = $size[0] - $corner_width;  
    $dest_y = 0;  
    $rotated = imagerotate($corner_resized, 270, 0);
    imagecolortransparent($rotated, $black); 
    imagecopymerge($image, $rotated, $dest_x, $dest_y, 0, 0, $corner_width, $corner_height, 100);  
}

// Rotate image
$image = imagerotate($image, $angle, $white);

// Output final image
imagejpeg($image);

// Remove temp files
imagedestroy($image);  
imagedestroy($corner_source);
?>

How to use it?

Needless to say, PHP and the GD library needs to be installed on your server. You’ll also need a png file of the corner. You can use one of our corner images if you want.

Just paste the code above and save it in a .php file. Make the necessary changes to the $images_dir and $corner_source variables (lines 10 and 11). Link the src attribute of your image to that file, using the following URL variables:

  • src: name of the image file
  • radius (optional): value that represents the radius (in pixels) of the corners; use this to resize the corner image
  • angle (optional): value that represents the rotation angle of the full image, in degrees
  • topleft=no (optional): do not round the top-left corner
  • bottomleft=no (optional): do not round the bottom-left corner
  • bottomright=no (optional): do not round the bottom-right corner
  • topright=no (optional): do not round the top-right corner

Examples

<img src='roundedCorners.php?src=image.jpg&radius=40' />
<img src='roundedCorners.php?src=image.jpg&radius=40&angle=15' />
<img src='roundedCorners.php?src=image.jpg&radius=40&topleft=no&bottomright=no' />

If this helped you save time or solve a problem,
please buy me a coffee (or beer ;) ) to show your appreciation
and help support my work!

I'm available for hire!

If you need help with a website (HTML/CSS/JavaScript/PHP/MySQL), blog (15 years of experience with WordPress) or web app, get in touch and let's discuss what I can bring to your project, big or small.