I’ve converted my rounded-corner bash script into a PHP function that’ll use the Image Magick command line tools to do the same. With some added functionality to handle automatically creating thumbnails and applying a background color to the source image itself. This also allows for the insertion of basic pre-processing and post-processing arguments to IM.
For more information and output examples see. the bash version.
To see an example of thumbnails generated with some pre-processing done:
This is a sample done with thumbnail pre-processing. That is processing done before the rounded corners are made.
With this sample, I switched colorspace to HSL and then set the hue and saturation to a constant before applying the glass-bubble rounded corners.
Known bug: sometimes the glass-bubble method will add a single pixel to the width, which is transparent. I believe passing -trim
in the postprocessing option may trim that off for you, though I have not thoroughly tested it.
Also: I have no idea if this will work on a Windows server.
/**
* Produce a thumbnail with rounded corners as specificed in options.
* @param String $in Input file name.
* @param String $out Output file name.
* @param Integer $width Width constraint of desired thumbnail. Omit with empty string.
* @param Integer $height Height of desired thumbnail. Omit with empty string.
* @param Array $options An array of options as such:
* method: plain or glass-bubble (Default: plain)
* radius: requested radius (Default: min($width, $height) * 0.2)
* if it calculates 0, this will default to 14.
* image-background: Background color applied to the image itself. (Default: '#000000')
* background: Background color behind an image (for the corners) (Default: transparent)
* A note for this: jpg output doesn't really like transparent.
* convertcommand: Override the path to the convert command. (default: convert)
* preprocessing: Additional preprocessing arguments you'd like to send IM for the preproc img
* postprocessing: Additional postprocessing arguments "" for the output thumbnail.
* @return Mixed String if error (contains error message) or array of image information.
*/
function rounded_thumbnail_im($in, $out, $width, $height, $options = array())
{
$convertcommand = 'convert';
$method = 'plain';
$imgback = '#000000';
$back = 'transparent';
$radius = floor(min($width, $height) * 0.2);
$preprocessing = '';
$postprocessing = '';
if($radius == 0)
{
$radius = 14;
}
if(isset($options['method']))
{
if(in_array($options['method'], array('plain', 'glass-bubble')))
{
$method = $options['method'];
}
}
if(isset($options['image-background'])) $options['imgback'] = $options['image-background'];
if(isset($options['background'])) $options['back'] = $options['background'];
foreach(array('imgback', 'back', 'convertcommand',
'radius', 'preprocessing', 'postprocessing') as $key)
{
if(isset($options[$key]))
{
$$key = $options[$key];
}
}
if(!is_file($in))
{
return "$in is not a file.";
}
$swidth = escapeshellarg($width);
$sheight = escapeshellarg($height);
$sradius = intval($radius);
$sinfile = escapeshellarg($in);
$soutfile = escapeshellarg($out);
$sbackground = escapeshellarg($back);
$simgbackground = escapeshellarg($imgback);
$spreproc = escapeshellcmd($preprocessing);
$spostproc = escapeshellcmd($postprocessing);
$sconv = escapeshellarg($convertcommand);
//Build preprocessor command.
$resize = '';
if($width != '' || $height != '')
{
$resize = "-resize {$swidth}x{$sheight}";
}
$preprocess = "$sconv $sinfile $resize -background $simgbackground -flatten $spreproc png:-";
//Post process:
if($back != 'transparent')
{
$backgroundproc = "png:- | $sconv png:- -background $sbackground -flatten $spostproc";
}
else
{
if($postprocessing == '')
{
$backgroundproc = "";
}
else
{
$backgroundproc = "png:- | $sconv png:- -background transparent $spostproc";
}
}
//Perform smashy smashy
if($method == 'plain')
{
$command="$preprocess | $sconv \\( png:-
\\( +clone -alpha extract
-draw \"fill black polygon 0,0 0,$sradius $sradius,0 fill white circle $sradius,$sradius $sradius,0\"
\\( +clone -flip \\) -compose Multiply -composite
\\( +clone -flop \\) -compose Multiply -composite
\\) -alpha off -compose CopyOpacity -composite \\) $backgroundproc $soutfile";
$command = preg_replace('/[\r\n]+/', '', $command);
//echo $command;
system($command);
if(is_file($out) && filesize($out) > 100)
{
return getimagesize($out);
}
else
{
return 'Plain rounded-corner conversion failed.';
}
}
else if ($method == 'glass-bubble')
{
//Removes the stream to standard out from the preprocess command.
//So we can use it slightly differently.
$preprocess = preg_replace('/png\:-$/', '', $preprocess);
$nfile = tempnam(sys_get_temp_dir(), 'GBb');
$snfile = escapeshellarg('png:'.$nfile);
system($cmd = "$preprocess $snfile");
//echo "$cmd\n";
$command="$sconv $snfile -alpha off -fill white -colorize 100%
-draw \"fill black polygon 0,0 0,$sradius $sradius,0 fill white circle $sradius,$sradius $sradius,0\"
\\( +clone -flip \\) -compose Multiply -composite
\\( +clone -flop \\) -compose Multiply -composite
-background Gray50 -alpha Shape png:- |
$sconv png:- -bordercolor None -border 1x1
-alpha Extract -blur 0x10 -shade 130x30 -alpha On
-background gray50 -alpha background -auto-level
-function polynomial 3.5,-5.05,2.05,0.3
\\( +clone -alpha extract -blur 0x3 \\)
-channel RGB -compose multiply -composite
+channel +compose -chop 1x1
png:- |
$sconv \\( $snfile -alpha Set png:-
\\( -clone 0,1 -alpha Opaque -compose Hardlight -composite \\)
-delete 0 -compose In -composite \\) $backgroundproc $soutfile 2>> debug.txt";
$command = preg_replace('/[\r\n]+/', '', $command);
//echo $command,"\n";
system($command);
if(is_file($nfile))
{
unlink($nfile);
}
if(is_file($out) && filesize($out) > 100)
{
return getimagesize($out);
}
else
{
return 'Glass-bubble rounded-corner conversion failed.';
}
}
}