将文本放入框中

发布于 2024-11-05 20:46:48 字数 422 浏览 1 评论 0原文

在我的网站上,我允许用户使用他们指定的在当前用于 imagemagick 转换的图片上绘制的文本行创建图片

- 我指定 svg 模板并让 Convert 完成剩下的工作,

这里是负责在中输出文本的代码的一部分图片

  <text text-anchor="middle" x="50%%" y="%s"
        font-family="Times New Roman" font-size="55"
        style="fill:rgb(255,255,255);">
    %s
  </text>

我的问题是,如果用户提供很长的字符串,则文本不适合图像。

如果文本不适合图片,我希望文本自动调整为较小的字体。可以使用 svg 模板吗?如果没有,还有什么其他解决方案

on my website i allow users to create pictures with line of text they specify drawn on the picture

currently i use for that imagemagick convert - i specify svg template and let convert do the rest

here is part of code which is responsible for outputting text in the picture

  <text text-anchor="middle" x="50%%" y="%s"
        font-family="Times New Roman" font-size="55"
        style="fill:rgb(255,255,255);">
    %s
  </text>

my problem is that if user provides very long strings, the text doesn't fit in the image.

i'd like text to be resized automatically to smaller font if it doesn't fit the picture. is it possible to do with svg templates? if not, what could be other solutions

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

家住魔仙堡 2024-11-12 20:46:48

您可以在 SVG 模板中添加一个脚本,该脚本在加载 SVG 时调用,并使用 getCompulatedTextLength() 来调整字体大小。这是一个有点老套的解决方案,但它似乎有效。

这是一个简单的示例,它绘制了一个框并在其中绘制了一些文本。应调整文本大小,使其始终适合框内,无论其长度有多长(至少到目前为止):

要在加载 SVG 时调用代码,请包含 onload="int(evt)"在 SVG 标签中。

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> 
<svg xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink"
     width="400" height="80"
     onload="init(evt)"> 

然后是实际的脚本:

  <script type="text/ecmascript">
    <![CDATA[
    
    function init(evt)
    {
        if ( window.svgDocument == null )
        {
            svgDocument = evt.target.ownerDocument;
        }

        maximum_length = 300;
        my_text = svgDocument.getElementById('text-to-resize');

        for (var font_size=55; font_size>0; font_size--)
        {
            if(my_text.getComputedTextLength() < maximum_length){break;}
            my_text.setAttributeNS(null, "font-size", font_size);
        }

    }
    
    ]]>
  </script>

我只是使用 for 循环来减小字体大小,直到文本长度小于指定的最大值;我确信有更好的方法来调整文本大小。

最后是实际的文本和框:

<rect id="rect1" x="20" y="10" width="320" height="50" fill="white" stroke="black"/>
<text id="text-to-resize"
      text-anchor="middle"
      x="170" y="50"
      font-family="Times New Roman" font-size="55">
 whatever text
</text>
</svg>

如果更改文本,字体大小应该更改以使其适合框内。您可能还需要更改 x 和 y 值以使文本正确居中。

You could add a script within the SVG template which called when the SVG is loaded and uses getComputedTextLength() to resize the font. It's a bit of a hacky solution, but it seems to work.

Here's a quick example that draws a box and some text inside it. The text should be resized to always fit in the box no matter how long it is (up to point at least):

To call the code when the SVG is loaded include onload="int(evt)" in the SVG tag.

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> 
<svg xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink"
     width="400" height="80"
     onload="init(evt)"> 

Then the actual script:

  <script type="text/ecmascript">
    <![CDATA[
    
    function init(evt)
    {
        if ( window.svgDocument == null )
        {
            svgDocument = evt.target.ownerDocument;
        }

        maximum_length = 300;
        my_text = svgDocument.getElementById('text-to-resize');

        for (var font_size=55; font_size>0; font_size--)
        {
            if(my_text.getComputedTextLength() < maximum_length){break;}
            my_text.setAttributeNS(null, "font-size", font_size);
        }

    }
    
    ]]>
  </script>

I just used a for loop to decrement the font-size until the text length is less than the maximum specified; I'm sure there's a better way to resize the text.

Finally the actual text and box:

<rect id="rect1" x="20" y="10" width="320" height="50" fill="white" stroke="black"/>
<text id="text-to-resize"
      text-anchor="middle"
      x="170" y="50"
      font-family="Times New Roman" font-size="55">
 whatever text
</text>
</svg>

If you change the text, the font-size should change so that it fits inside the box. You'll probably want to change the x- and y- values to correctly centre the text too.

酒废 2024-11-12 20:46:48

通过放弃 svg 并使用 imagemagick Convert 和 mvg 模板完成所有操作来解决

这里是简化的脚本示例,以防有人追求类似的

脚本将图像和标题放在画布上。标题是使用单独的转换命令创建的,保存为临时文件,然后放在画布上

#!/bin/sh

TEMPLATE="
push graphic-context
viewbox 0 0 600 600 
affine 1 0 0 1 0.0 0.0
push graphic-context
fill 'rgb(0,0,0)'
rectangle 0,0 600,600
pop graphic-context
push graphic-context
image Over 38,38 338,338 '%s' 
pop graphic-context
push graphic-context
image Over 36,400 529,55 '%s' 
pop graphic-context
pop graphic-context
";

#1. creating label fitting specified proportions 
#2. converting mvg template to jpeg image (and trimming it in process) 
#3. removing temp file with label

convert -size 529x55 -background black -family "Times New Roman" -gravity center -fill white label:"$2" "tmp/$1title.jpg" && printf "$TEMPLATE"  "images/$1.jpg" "tmp/$1title.jpg"  | convert mvg:- -trim +repage -bordercolor black -border 36  "images/$1converted.jpg" && rm "tmp/$1title.jpg"

#script parameters: $1 is image id, $2 is title text

solved by abandoning svg and doing everything with imagemagick convert and mvg template

here's the simplified script example in case anyone's pursuing something similar

script is putting an image and a title on the canvas. title is created with separate convert command, saved as temporary file and then put onto the canvas

#!/bin/sh

TEMPLATE="
push graphic-context
viewbox 0 0 600 600 
affine 1 0 0 1 0.0 0.0
push graphic-context
fill 'rgb(0,0,0)'
rectangle 0,0 600,600
pop graphic-context
push graphic-context
image Over 38,38 338,338 '%s' 
pop graphic-context
push graphic-context
image Over 36,400 529,55 '%s' 
pop graphic-context
pop graphic-context
";

#1. creating label fitting specified proportions 
#2. converting mvg template to jpeg image (and trimming it in process) 
#3. removing temp file with label

convert -size 529x55 -background black -family "Times New Roman" -gravity center -fill white label:"$2" "tmp/$1title.jpg" && printf "$TEMPLATE"  "images/$1.jpg" "tmp/$1title.jpg"  | convert mvg:- -trim +repage -bordercolor black -border 36  "images/$1converted.jpg" && rm "tmp/$1title.jpg"

#script parameters: $1 is image id, $2 is title text
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文