Скругление уголков изображения с прозрачностью при помощи GD

06 Oct 2009
<?php
$filename = 'image.jpg';
$radius = 15;

/**
 * Чем выше rate, тем лучше качество сглаживания и больше время обработки и
 * потребление памяти.
 *  
 * Оптимальный rate подбирается в зависимости от радиуса.
 */

$rate = 3;

$img = imagecreatefromstring(file_get_contents($filename));
imagealphablending($img, false);
imagesavealpha($img, true);

$width = imagesx($img);
$height = imagesy($img);

$rs_radius = $radius * $rate;
$rs_size = $rs_radius * 2;

$corner = imagecreatetruecolor($rs_size, $rs_size);
imagealphablending($corner, false);

$trans = imagecolorallocatealpha($corner, 255, 255, 255, 127);
imagefill($corner, 0, 0, $trans);

$positions = array(
    array(0, 0, 0, 0),
    array($rs_radius, 0, $width - $radius, 0),
    array($rs_radius, $rs_radius, $width - $radius, $height - $radius),
    array(0, $rs_radius, 0, $height - $radius),
);

foreach ($positions as $pos) {
    imagecopyresampled($corner, $img, $pos[0], $pos[1], $pos[2], $pos[3], $rs_radius, $rs_radius, $radius, $radius);
}

$lx = $ly = 0;
$i = -$rs_radius;
$y2 = -$i;
$r_2 = $rs_radius * $rs_radius;

for (; $i <= $y2; $i++) {

    $y = $i;
    $x = sqrt($r_2 - $y * $y);

    $y += $rs_radius;
    $x += $rs_radius;

    imageline($corner, $x, $y, $rs_size, $y, $trans);
    imageline($corner, 0, $y, $rs_size - $x, $y, $trans);

    $lx = $x;
    $ly = $y;
}

foreach ($positions as $i => $pos) {
    imagecopyresampled($img, $corner, $pos[2], $pos[3], $pos[0], $pos[1], $radius, $radius, $rs_radius, $rs_radius);
}

header('Content-Type: image/png');
imagepng($img);
нет тэгов
27 Oct 2009 list
а можно сделать, чтобы только верхние 2 края закруглялись, а нижние остались квадратными?
29 Oct 2009 Sergey89
Да. Нужно только убрать лишние позиции для скругления.

$positions = array(
array(0, 0, 0, 0),
array($rs_radius, 0, $width - $radius, 0)
);
03 Jul 2010 Milka
Огромное спасибо за статью, очень пригодилась!
24 Aug 2010 Prodev
Спасибо за алгоритм!
Чтобы упростить набор исходных параметры сделал:
$rate = round($radius / 3);
13 Dec 2010 1111
а как указать свой размер?:(
06 Feb 2011 kostyl
Автор, чё молчишь? Пиши!!!

Имя:

Сообщение: