Я прошел через несколько решений и не могу найти быстрый и эффективный способ добавления динамического многострочного текста / заголовка / аннотации к изображению с помощью IMagick.
Сценарий будет принимать данные JSON для нескольких текстовых областей для применения к изображению, и данные включают в себя все атрибуты шрифта: обводка, цвет, тень, выравнивание, X & Местоположение Y (для верхнего левого угла), максимальная ширина и вращение.
Я пробовал несколько методов аннотации и подписи и просто не могу заставить текст вести себя. Вот что я хотел бы сделать:
И вот мой код:
$data = '{
"baseImage" : "test-image.jpg",
"fields" : [
{
"name" : "name",
"default" : "You"},
{
"name" : "email",
"default" : "[email protected]"}
],
"textareas": [
{
"font": "Alpha-Echo",
"align" : "left",
"size" : 24,
"color" : "#990000",
"stroke" : {
"color" : "#000000",
"width" : 0
},
"shadow" : {
"x" : 2,
"y" : 2,
"blur" : 6,
"color" : "#000000",
"opacity" : 0.5
},
"width" : 400,
"rotation" : 0,
"x" : 10,
"y" : 10,
"text" : "Welcome, {name}! How are you doing today?"}
]
}';
$json = json_decode($data);
$imgBase->setBackgroundColor(new ImagickPixel('transparent'));
$imgBase->readImage($json->baseImage);
$imgBase->setImageFormat('png');
// get image dimensions
$w = $imgBase->getImageWidth();
$h = $imgBase->getImageHeight();
// loop through the textareas and fields
foreach($json->textareas as $textarea){
$captionHeight = $h - $textarea->y;
$drawText = $textarea->text;
foreach($json->fields as $field){
$fieldText = (!empty($_GET[$field->name]))? $_GET[$field->name] : $field->default;
$drawText = str_replace ('{' . $field->name . '}' , $fieldText , $drawText);
}
// create the caption
$theText = new Imagick();
$theText->newImage($textarea->width, $captionHeight, new ImagickPixel('transparent'));
$draw = new ImagickDraw();
if($textarea->stroke->width > 0){
$draw->setStrokeOpacity(1);
$draw->setStrokeColor($textarea->stroke->color);
$draw->setStrokeWidth($textarea->stroke->width);
$draw->setStrokeAntialias(true);
}
$draw->setGravity(1); // NORTH
$draw->setTextAlignment($alignment[$textarea->align]); // left = 1, center = 2, right = 3
$draw->setTextAntialias(true);
$draw->setFont($textarea->font);
$draw->setFontSize($textarea->size);
$draw->setFillColor($textarea->color);
$draw->rotate($textarea->rotation);
$draw->annotation($textarea->x, $textarea->y, $drawText);
$imgBase->drawImage($draw);
}
echo $imgBase->getImageBlob();
У меня есть проблемы
Я предполагаю, что это может быть сделано — это доступно в версии командной строки ImageMagick (http://www.imagemagick.org/Usage/text/#caption_bestfit) но IMagick это другая история. Любая помощь очень ценится!
Это скорее комментарий, чем ответ, но он длился долго.
Если вы уже вызываете новые временные экземпляры Imagick с $theText
, тогда почему бы просто не следовать методу наилучшего соответствия заголовка и скомпоновать (а не нарисовать) полученное изображение поверх основного изображения?
$theText = new Imagick();
// Apply all font attributes.
... // omitted
// Create a `caption:` pseudo image that only manages text.
$theText->newPseudoImage($textarea->width,
$imgBase->height,
'caption:'.$textarea->text);
// Remove extra height.
$theText->trimImage(0.0);
// Compiste bestfit caption over base image.
$imgBase->compositeImage($theText,
Imagick::COMPOSITE_ATOP,
$textarea->x,
$textarea->y);
Других решений пока нет …