Постановка задачи: есть несколько тысяч картинок-миниатюр с прямыми углами. Необходимо преобразовать их таким образом, чтобы углы были закруглёнными.
Кто-то будет писать PHP-скрипт, кто-то — использовать PhotoShop, а для любителей командной строки и ImageMagick есть более простое решение.
Итак, пусть у нас имеется такое исходное изображение (размер изображения — 96×96, но для описываемого метода это не важно):
Для начала нам надо рассчитать параметры рамки:
Высота и ширина берутся непосредственно из файла, а результаты вычислений сохраняются в файле формата Magick Vector Graphics и будут использоваться далее. Перед проведением вычислений к файлу добавляется двухпиксельная рамка. Таким образом, размер изображения с рамкой (концы которой будут закругляться) составит 100×100.
Теперь нам нужно сгенерировать оверлей и маску:
convert source.png -border 2 -matte -channel RGBA -threshold -1 -background none -fill white -stroke black -strokewidth 1 -draw "@rounded_corner.mvg" mask.png
Оверлей представляет собой рамку с закругленными концами, которая будет накладываться на исходное изображение. Маска же используется для стирания лишних частей изображения. Ширина штриха маски меньше ширины штриха оверлея: хотя будет стёрто чуть большее по площади изображение, края изображения будут сглажены должным образом. Цвет рамки задаётся в параметре stroke
.
Для изображений одного размера оверлей и маска будут одинаковыми. Поэтому при обработке большого количества изображений есть смысл генерировать их один раз.
Формируем окончательное изображение:
Получим следующее изображение:
Над изображением можно извратиться и получить более красивую рамку:
Есть еще один способ закругления углов (в этом случае ни маска, ни оверлей не нужны):
Как обработать коллекцию файлов? В Linux это просто: я приведу общий случай:
PS — а еще можно и тень добавить:
Я правильно понял что это пакетная обработка изображений, а не изменение картинки (скажем при аплоаде) на картинку с закругленными углами?
Всё относительно Описанную процедуру можно применять и при аплоаде.
В одном из проектов я использовал этот метод для генерации миниатюр при аплоаде:
{
global $smarty;
$mask = IMAGES_DIR . '/' . $smarty->skin . '/photos/mask.png';
$overlay = IMAGES_DIR . '/' . $smarty->skin . '/photos/overlay.png';
$options = "\"{$src}\"" . ' -compress JPEG ';
$error = '';
$output = array();
$retval = 0;
$hash = $this->getHash($id);
if (false == empty($dims) && 0 != $dims[0]) {
$options .= " -resize \"{$dims[0]}x{$dims[0]}\" ";
}
$path = $this->makeDirs(PHOTOS_DIR . '/full', $hash);
$dst = $path . '/' . $id . '.jpg';
$options .= ' ' . $dst;
exec(IMAGE_MAGICK_CONVERT . ' ' . $options, $output, $retval);
if (0 != $retval) {
$error = "Error ({$retval}): " . join(' ', $output) . " ({$dst})";
return false;
}
$converted = array($dst);
$failed = false;
if (count($dims) > 1) {
for ($i=1; $i<count($dims); ++$i) {
$options = "\"{$src}\"" . " -thumbnail \"{$dims[$i]}x{$dims[$i]}\" -quality 90 ";
$path = $this->makeDirs(PHOTOS_DIR . "/{$dims[$i]}x{$dims[$i]}", $hash);
$dst = $path . '/' . $id . '.jpg';
$size = $dims[$i];
//===========================================
$options .= " -size {$size}x{$size} xc:#999999 +swap " .
"-gravity center -composite -matte -bordercolor none " .
"-border 2 {$mask} -compose DstIn -composite {$overlay} " .
"-compose Over -composite -depth 8 -quality 95 -matte " .
"-virtual-pixel transparent -channel A -blur 0x8 " .
"-evaluate subtract 50% -evaluate multiply 2.001 " . $dst;
exec(IMAGE_MAGICK_CONVERT . ' ' . $options, $output, $retval);
//===========================================
if (0 != $retval) {
$error = "Error ({$retval}): " . join(' ', $output) . " ({$dst})";
$failed = true;
break;
}
$converted[] = $dst;
chmod($dst, 0666);
}
}
if (true == $failed) {
foreach ($converted as $file) {
@unlink($file);
}
return false;
}
return true;
}