簡體   English   中英

如何在 svgwrite 中實現文本換行?

[英]How to implement text wrapping in svgwrite?

我在 python 中使用 svgwrite 根據我的 Tensorflow 模型生成輸出以輸出模擬手寫文本。 我當前的設置需要一個字符串數組來表示換行符,但是生成的文本大小不一致,有時會在行中的最后一個單詞之后呈現尷尬的間距,例如這

是否可以將文本換行添加到單個長行中,當當前行達到給定的最大寬度時會自動添加換行符? Google 搜索將我帶到 svgwrite 頁面並建議使用TextArea,但給出的示例是 HTML。

    def _draw(self, strokes, lines, filename, stroke_colors=None, \
          stroke_widths=None, background_color='white'):

    lines = [
        "Lorem ipsum dolor sit amet, consectetur adipiscing elit,",
        "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
        "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris",
        "nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in",
        "reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur."
    ]

    stroke_colors = stroke_colors or ['black']*len(lines)
    stroke_widths = stroke_widths or [2]*len(lines)

    line_height = 35
    view_width = 152.4
    view_height = 101.6

    dwg = svgwrite.Drawing(filename=filename)
    dwg.viewbox(width=view_width, height=view_height)
    dwg.add(dwg.rect(insert=(0, 0), size=('153mm', '102mm'), fill=background_color))

    for i in range(3):
            
        
        initial_coord = np.array([30,-((i*450)+25)])
        strokesc = self._sample(lines, [1 for i in lines], [7 for i in lines]);
        
        for offsets, line, color, width in zip(strokesc, lines, stroke_colors, stroke_widths):

            if not line:
                initial_coord[1] -= line_height
                continue
            offsets[:, :2] *= random.randint(150, 190)/100
            strokesc = drawing.offsets_to_coords(offsets)
            strokesc = drawing.denoise(strokesc)
            strokesc[:, :2] = drawing.align(strokesc[:, :2])

            strokesc[:, 1] *= -1
            strokesc[:, :2] -= strokesc[:, :2].min() + initial_coord

            prev_eos = 1.0
            p = "M{},{} ".format(0, 0)
            for x, y, eos in zip(*strokesc.T):
                p += '{}{},{} '.format('M' if prev_eos == 1.0 else 'L', x, y)
                prev_eos = eos
            path = svgwrite.path.Path(p)
            path = path.stroke(color=color, width=width, linecap='round').fill("none")
            dwg.add(path)

            initial_coord[1] -= line_height

    dwg.save()

這是我當前在 python 中的解決方案,它輸出上面的示例

您可以嘗試直接處理文本:

my_text = sum(lines)
nb_lines = len(lines)


nb_words_per_line = len(my_text.split()) // nb_lines

new_lines = []
cmpt = 0
tmp = ""
for i, word in enumerate(my_text.split()):
    
    if cmpt%nb_words_per_line == 0:
        new_lines.append(tmp)
        tmp = ""
    tmp += word + " "

if tmp:
    new_lines.append(tmp)
    

然后,您可以像之前使用的lines一樣使用new_lines

所以你只想用預定義的最大數量包裝文本。 人物?
我猜你正在尋找 python 的原生textwrap

textwrap 模塊提供了一些方便的功能,以及完成所有工作的類 TextWrapper。 如果你只是包裝或填充一兩個文本字符串,便利功能應該足夠了; 否則,您應該使用 TextWrapper 實例以提高效率。

import textwrap

lines = [
    "Lorem ipsum dolor sit amet, consectetur adipiscing elit,",
    "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
    "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris",
    "nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in",
    "reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur."
]

textwrap.wrap(" ".join(lines), 40)

>>> Out:
>>> ['Lorem ipsum dolor sit amet, consectetur',
>>> 'adipiscing elit, sed do eiusmod tempor',
>>> 'incididunt ut labore et dolore magna',
>>> 'aliqua. Ut enim ad minim veniam, quis',
>>> 'nostrud exercitation ullamco laboris',
>>> 'nisi ut aliquip ex ea commodo consequat.',
>>> 'Duis aute irure dolor in reprehenderit',
>>> 'in voluptate velit esse cillum dolore eu',
>>> 'fugiat nulla pariatur.']

或者,如果您直接想用換行符連接結果字符串列表:

textwrap.fill(" ".join(lines), 40)
>>> Out:
>>> 'Lorem ipsum dolor sit amet, consectetur\nadipiscing elit, sed do eiusmod tempor\nincididunt ut labore et dolore magna\naliqua. Ut enim ad minim veniam, quis\nnostrud exercitation ullamco laboris\nnisi ut aliquip ex ea commodo consequat.\nDuis aute irure dolor in reprehenderit\nin voluptate velit esse cillum dolore eu\nfugiat nulla pariatur.'

更新:渲染文本的理由:

渲染文本的“實際”對齊是通過指定“textLength”屬性來實現的(有關更多詳細信息和選項,請參見此處此處)。

import sys
import svgwrite

import textwrap

lines = [
    "Lorem ipsum dolor sit amet, consectetur adipiscing elit,",
    "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
    "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris",
    "nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in",
    "reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur."
]

# wrap text to max. 40 characters
usetext = textwrap.wrap(" ".join(lines), 40)

filename = sys.argv[0].rstrip('.py')

def create_svg(name):
    svg_width = 500
    svg_height = 300

    font_size = 20
    dwg = svgwrite.Drawing(name, (svg_width, svg_height), debug=True)
    # background will be white.
    dwg.add(dwg.rect(insert=(0, 0), size=('100%', '100%'), fill='white'))
    
    for i, line in enumerate(usetext):
        dwg.add(dwg.text(line, insert=(0,  font_size * (i + 4)),
                font_family="serif", font_size=font_size, fill='black',
                textLength=svg_width),
                )
    
    dwg.save()

if __name__ == '__main__':
    create_svg(filename + '.svg')

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM