我目前正在与一个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
预期结果:该文本应环绕到下一行。
我不知道一个文本包装可以根据你的情况下帮助,因为你需要分别绘制每一行。
好像你应该计算在单行字符的最大长度,然后执行:
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.
因为你面对的字体,你会想知道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
请注意,这是基于字符的,而不是文字为基础的,所以它那种很烂。而且,由于大多数字体是成比例,比例大概是错的。您可能能够调整使用它的一些启发,包括一组内置宽度假设。 (只计算所有字母的宽度一次,将它们存储在一个表,并承担所有的字体使用宽度 - 仍然是错的,但通常比比值法,并更快更好的逼近!)