Мне нужно знать, как можно маскировать любое квадратное изображение с помощью Imagick. Вот код, который я до сих пор, но изображение просто не получить маскироваться должным образом:Изображения маски с созданным изображением Imagick
Получить изображение
$srcFile = 'filename.png';
$image = new Imagick($srcFile);
Crop изображение на площади
$d = $image->getImageGeometry();
$src_width = $d['width'];
$src_height = $d['height'];
$thumbSize = min(max($src_width, $src_height), abs($thumbSize));
if ($src_width < $src_height) {
$image->cropImage($src_width, $src_width, 0, (($src_height - $src_width)/2));
} else {
$image->cropImage($src_height, $src_height, (($src_width - $src_height)/2), 0);
}
Изменить размер изображения
$image->thumbnailImage($thumbSize, $thumbSize, 1);
Crop/Маска изображения с формой Безье
$image->compositeImage(bezier($thumbSize, $thumbSize), Imagick::COMPOSITE_COPYOPACITY, 0, 0);
Функция Безье создает форму вида:
function bezier($width, $height) {
$fillColor = "#000";
$draw = new ImagickDraw();
Заполните немаскированную часть с черным цветом
$fillColor = new ImagickPixel($fillColor);
$draw->setFillColor($fillColor);
$smoothPointsSet = [
[
['x' => 0.0 * $width, 'y' => 0.5 * $width],
['x' => 0.0 * $width, 'y' => 0.905 * $width],
['x' => 0.095 * $width, 'y' => 1.0 * $width],
['x' => 0.5 * $width, 'y' => 1.0 * $width]
], [
['x' => 0.5 * $width, 'y' => 1.0 * $width],
['x' => 0.905 * $width, 'y' => 1.0 * $width],
['x' => 1.0 * $width, 'y' => 0.905 * $width],
['x' => 1.0 * $width, 'y' => 0.5 * $width]
], [
['x' => 1.0 * $width, 'y' => 0.5 * $width],
['x' => 1.0 * $width, 'y' => 0.095 * $width],
['x' => 0.905 * $width, 'y' => 0.0 * $width],
['x' => 0.5 * $width, 'y' => 0.0 * $width]
], [
['x' => 0.5 * $width, 'y' => 0.0 * $width],
['x' => 0.095 * $width, 'y' => 0.0 * $width],
['x' => 0.0 * $width, 'y' => 0.095 * $width],
['x' => 0.0 * $width, 'y' => 0.5 * $width]
]
];
foreach ($smoothPointsSet as $points) {
$draw->bezier($points);
}
Безье точек не заполняют квадрат в середине, так заполнить его вручную
$points = [
['x' => $width * 0.5, 'y' => 0.0],
['x' => 0.0, 'y' => $height * 0.5],
['x' => $width * 0.5, 'y' => $height],
['x' => $width, 'y' => $height * 0.5]
];
$draw->polygon($points);
Скопируйте ящик изображение в новый прозрачный Imagick изображение
$imagick = new Imagick();
$imagick->newImage($width, $width, "none");
Здесь я экспериментировал с различными свойствами. Я не получил удовлетворительного результата - изображение почти всегда не маскируется.
#$imagick->setImageAlphaChannel(Imagick::ALPHACHANNEL_SHAPE);
#$imagick->setImageFormat("png");
$imagick->drawImage($draw);
#$imagick->setImageMatte(false);
return $imagick;
}
Я был бы очень рад, если бы я мог знать, где проблема и как ее исправить. Я нашел различные ответы на SO, которые не работали для меня:
Используйте $dude->setImageMatte(1);
Using a transparent PNG as a clip mask
Используйте $base->compositeImage($mask, Imagick::COMPOSITE_DSTIN, 0, 0, Imagick::CHANNEL_ALPHA);
How to use Imagick to merge and mask images?
К сожалению, я не смог решить эту проблему.
Это стоит идея отправить в список рассылки ImageMagick, или ударить свой IRC канал, или независимо от способа их непосредственного контакта заключается в том, чтобы сообщить им, что магия изображения, по-видимому, не предупреждает пользователей, когда они сохраняют изображения в формате, который не поддерживает используемые функции. Сохранение изображения с альфа-каналом в растровом изображении, поскольку JPEG должен иметь хотя бы предупреждение о консоли, которое позволило бы вам сразу обнаружить и устранить проблему. –
", чтобы сообщить им, что магия изображения, по-видимому, не предупреждает пользователей, когда они сохраняют изображения в формате« Это, вероятно, по дизайну. Философия, стоящая за C api, которую предоставляет ImageMagick, заключается в том, чтобы делать то, что пользователь говорит ей, исходя из предположения, что они знают, что они делают. Сохранение изображения с прозрачностью, поскольку Jpeg - это обычная вещь (иногда), поэтому она просто делает это, а не сомневается в том, что пользователь намеревался. – Danack