How can I wrap text using Imagick in PHP so that it is drawn as multiline text?

前端 未结 5 1465
悲哀的现实
悲哀的现实 2020-12-05 16:54

The Imagick library in PHP allows you to draw text on top of an image.

How can I tell Imagick to wrap the text based upon some bounded text box, so that the words ap

5条回答
  •  遥遥无期
    2020-12-05 17:33

    Hi i find some sollution thanks for BMinner for his code i edit his code and get good working sollution

    USAGE

    newImage($w,$h,new ImagickPixel('green'),'png');
    
    
    $draw = new ImagickDraw();
    $draw->setFontSize(25);
    
    $text="SomeTextWithoutSpacesAndGoingOn..xxxxx 

    some short words with spaces

    and some text
    with manuel page
    break

    and also multiple spaces spaces end. also w i t o n e c ha ra c ter"; list($lines, $lineHeight)= wordWrapAnnotation($canvas, $draw, $text, $w-20); $canvas->annotateImage($draw, 10, $lineHeight , 0, $lines); header("Content-Type: image/png"); echo $canvas; ?>

    FUNCTIONS REFERANCED FROM BMinner

     0) {
            $ret = array();
            $len = mb_strlen($str, "UTF-8");
            for ($i = 0; $i < $len; $i += $l) {
                $ret[] = mb_substr($str, $i, $l, "UTF-8");
            }
            return $ret;
        }
        return preg_split("//u", $str, -1, PREG_SPLIT_NO_EMPTY);
    } 
    
    
    
    
    
    
    
    
    
    
    //this is my function detects long words and split them 
    
     function check_long_words($image,$draw,$text,$maxWidth) {
        $metrics = $image->queryFontMetrics($draw, $text);
        if($metrics['textWidth'] <= $maxWidth)
        return array($text);
    
    $words = str_split_unicode($text);
    
    
    
    $i = 0;
    
     while($i < count($words) )
        {
            $currentLine = $words[$i];
            if($i+1 >= count($words))
            {
    
                 $lines[] = $currentLine;
                //$lines = $lines + $checked;
                break;
            }
            //Check to see if we can add another word to this line
            $metrics = $image->queryFontMetrics($draw, $currentLine . $words[$i+1]);
    
            while($metrics['textWidth'] <= $maxWidth)
            {
                //If so, do it and keep doing it!
                $currentLine .= $words[++$i];
                if($i+1 >= count($words))
                    break;
                $metrics = $image->queryFontMetrics($draw, $currentLine . ' ' . $words[$i+1]);
                $t++;
            }
            //We can't add the next word to this line, so loop to the next line
    
    
                $lines[] = $currentLine;
    
            $i++;
    
        }
    
    
    return $lines;
    
    }   
    
    
    
    
    
    
    
    
    //this is BMiner code some fixes for manule breaks
    function wordWrapAnnotation(&$image, &$draw, $text, $maxWidth)
    {
        $brler = explode("
    ", $text); $lines = array(); foreach($brler as $br) { $i = 0; $words = explode(" ", $br); while($i < count($words) ) { $currentLine = $words[$i]; $metrics = $image->queryFontMetrics($draw, $currentLine . ' ' . $words[$i+1]); if($i+1 >= count($words)) { $checked=check_long_words($image,$draw,$currentLine,$maxWidth); $lines = array_merge($lines, $checked); if($metrics['textHeight'] > $lineHeight) $lineHeight = $metrics['textHeight']; //$lines = $lines + $checked; break; } //Check to see if we can add another word to this line while($metrics['textWidth'] <= $maxWidth) { //If so, do it and keep doing it! $currentLine .= ' ' . $words[++$i]; if($i+1 >= count($words)) break; $metrics = $image->queryFontMetrics($draw, $currentLine . ' ' . $words[$i+1]); $t++; } //We can't add the next word to this line, so loop to the next line $checked=check_long_words($image,$draw,$currentLine,$maxWidth); $lines = array_merge($lines, $checked); $i++; //Finally, update line height if($metrics['textHeight'] > $lineHeight) $lineHeight = $metrics['textHeight']; } } return array(join("\n",$lines), $lineHeight); } ?>

    AND OUTPUT

    enter image description here

提交回复
热议问题