如何使用IMagick为图像添加多行/自动装配,最大宽度的动态文本?

时间:2016-06-11 17:43:26

标签: php image-processing imagemagick image-manipulation imagick

我已经通过多种解决方案,并且无法使用IMagick快速有效地为图像添加动态,多行文字/字幕/注释。

该脚本将获取几个文本区域的JSON数据以应用于图像,并且数据包括所有字体属性:笔画,颜色,投影,对齐,X& Y位置(左上角),最大宽度和旋转。

我已经尝试了几种注释和字幕方法,并且根本无法让文字表现出来。以下是我希望能够做到的事:enter image description here

到目前为止,这是我的代码:

    $data = '{
    "baseImage" : "test-image.jpg",
    "fields" : [
        {
            "name" : "name",
            "default" : "You"
        },
        {
            "name" : "email",
            "default" : "you@yoursite.com"
        }
    ],
    "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();

我遇到的问题是

  1. 自动包装文字
  2. 保持最大宽度
  3. 定位(居中将文本向上和向左放置而不是水平居中文本等)
  4. 我假设它可以完成 - 它可以在ImageMagick(http://www.imagemagick.org/Usage/text/#caption_bestfit)的命令行版本中使用,但IMagick是另一回事。非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

这更像是一个评论然后答案,但是很长时间。

如果您已经使用$theText调用了一个新的临时Imagick实例,那么为什么不按照标题最佳匹配技术,并在基本图像上合成(而不是绘制)生成的图像?

$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);