一个人如何拆分非明确给出字符串转换成两个或更多的线?

问题描述 投票:-1回答:2

我目前正在与一个Python机器人将图像与文本输出的工作,但我发现,通常情况下的文本太长呈现。因此,我决定将字符串分成两行,因此它可以适合我的形象。我利用枕头5.1图像manipulaton。

我是一个新手到Python编程,我已经试图寻找如何将Python字符串分成两个或更多的线路。不幸的是,所有的结果似乎只能用显式给出(即“字符串”)字符串处理。

print("Ababoubian wisdom!")
ababou2 = ababou() #returns a string, how to split into two lines?
if("Ababou" in ababou2):
    ababou2 = ababou()
font = ImageFont.truetype("Arial.ttf", 14)
img = Image.new('RGB', (300, 200), color = (random.randint(0, 255),random.randint(0, 255), random.randint(0, 255)))
d = ImageDraw.Draw(img)
d.text((0, 0), ababou2, font=font) #draws text

Actual results

预期结果:该文本应环绕到下一行。

python word-wrap
2个回答
1
投票

我不知道一个文本包装可以根据你的情况下帮助,因为你需要分别绘制每一行。

好像你应该计算在单行字符的最大长度,然后执行:

ababou2 = ababou() # Whats the point of assigning the same value twice? 
                   # does ababou() returns a different value each time?
if "Ababou" in ababou2:
    ababou2 = ababou()

res_text = list()
ababou2 = ababou2.split(' ') # Splits the string by space\ ' ', to a list of strings 
curr_txt = ''
for word in ababou2:
    if len(curr_txt) < MAX_CHARS_PER_LINE: # This you need to figure out
        curr_txt += ' '  + word
    else:
        res_text.append(curr_txt)
        curr_txt = word

font = ImageFont.truetype("Arial.ttf", 14)
img = Image.new('RGB', (300, 200), color = (random.randint(0, 255),random.randint(0, 255), random.randint(0, 255)))
d = ImageDraw.Draw(img)
y = 0
for line in res_text:
    d.text((0, y), line, font=font) #draws text
    y += SINGLE_ROW_SPACE # Figure out what is the distance between two rows.

2
投票

因为你面对的字体,你会想知道getsize方法。这将帮助你弄清楚如何分割文本。

假设你有一个字符串:

def get_a_string():
    return "here is some string"

text = get_a_string()

现在,你也有具有宽度和高度的图像:

bgcolor = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
img = Image.new('RGB', (300, 200), color=bgcolor)

# Read the size tuple, unpack into height, width
img_height, img_width = img.size

如果文本太长,应该缩短:

font = ImageFont.truetype("Arial.ttf", 14)

text_height, text_width = font.getsize(text)

if text_width > (0.95 * img_width):
    # Not enough room. Break the text
    lines = split_by_words()

你怎么能缩短?首先,请尝试使用单词边界:

def split_by_words(text):
    text = text.rstrip() # Strip trailing whitespace

    words = text.split()
    lines = []

    while words:
        # I use None instead of '' to allow for leading spaces
        line = None

        for i, word in enumerate(words):
            new_line = word if line is None else line + ' ' + word
            (h, w) = font.getsize(new_line)

            if w > img_width:
                # New line won't fit? Break, keeping old line value.
                break
            else:
                # Still fits? Save it!
                line = new_line

        if i == 0:
            # First word was too long. Try character-by-character
            lines.extend(split_by_character(words[0]))
            # TODO: You might want to put lines[-1] into words[0] to join long first word
            # remainder with short second word.
            words = words[1:]
        else:
            lines.append(line)
            words = words[i:]

    return lines

这会调用getsize一堆倍,这可能是昂贵的。 (或不:!如果你生成从猫图片模因它可能因为文本是短期成本并不高。如果你正在写一个字处理器,提防)

另一种方法是计算原始文本的尺寸,然后假定所有字符都是相同的宽度,并作出关于在分割应根据图像尺寸的文字尺寸的比率猜测:

th, tw = font.getsize(text)
ih, iw = img.size

ratio = iw / tw  # 300 / 622, say
split_pos = int(len(text) * ratio)  # 0.51 * text len, about halfway along

line1 = text[:split_pos]

if font.getsize(line1) > iw:
    while True:
        split_pos -= 1
        line1 = line1[:-1]
        if font.getsize(line1) <= iw:
            break
else: # too short
    while True:
        line1 += text[split_pos]
        if font.getsize(line1) > iw:
            line1 = line1[:-1]
            break
        split_pos += 1

请注意,这是基于字符的,而不是文字为基础的,所以它那种很烂。而且,由于大多数字体是成比例,比例大概是错的。您可能能够调整使用它的一些启发,包括一组内置宽度假设。 (只计算所有字母的宽度一次,将它们存储在一个表,并承担所有的字体使用宽度 - 仍然是错的,但通常比比值法,并更快更好的逼近!)

© www.soinside.com 2019 - 2024. All rights reserved.