2011-10-08 74 views
23

我嘗試在圖像底部添加文本,實際上我已經完成了它,但是如果我的文本長度較長,則圖像寬度會從兩側剪切,以簡化我的工作如果文本長度大於圖像寬度,則多行文本。這裏是我的代碼:python PIL在圖像上繪製多行文本

FOREGROUND = (255, 255, 255) 
WIDTH = 375 
HEIGHT = 50 
TEXT = 'Chyba najwyższy czas zadać to pytanie na śniadanie \n Chyba najwyższy czas zadać to pytanie na śniadanie' 
font_path = '/Library/Fonts/Arial.ttf' 
font = ImageFont.truetype(font_path, 14, encoding='unic') 
text = TEXT.decode('utf-8') 
(width, height) = font.getsize(text) 

x = Image.open('media/converty/image.png') 
y = ImageOps.expand(x,border=2,fill='white') 
y = ImageOps.expand(y,border=30,fill='black') 

w, h = y.size 
bg = Image.new('RGBA', (w, 1000), "#000000") 

W, H = bg.size 
xo, yo = (W-w)/2, (H-h)/2 
bg.paste(y, (xo, 0, xo+w, h)) 
draw = ImageDraw.Draw(bg) 
draw.text(((w - width)/2, w), text, font=font, fill=FOREGROUND) 


bg.show() 
bg.save('media/converty/test.png') 

回答

33

你可以使用textwrap.wrap打破text成字符串列表,每個長最多width字符:

import textwrap 
lines = textwrap.wrap(text, width=40) 
y_text = h 
for line in lines: 
    width, height = font.getsize(line) 
    draw.text(((w - width)/2, y_text), line, font=font, fill=FOREGROUND) 
    y_text += height 
+0

非常感謝!只需複製和粘貼,它就像一個魅力。你是最好的:) – user985541

+0

'40'代表什麼? – User

+1

@用戶'40'代表最大字符數。這意味着它將允許最多或40個字符,然後再換行。但是,如果一個單詞是10個字符,然後下一個單詞是31個單詞,它將在第一個單詞之後換行,因爲它不能適合該行的第一個和第二個單詞。 – teewuane

0
text = textwrap.fill("test ",width=35) 
self.draw.text((x, y), text, font=font, fill="Black") 
+1

歡迎來到SO!你能否善意地解釋這是如何解決這個問題的?一些額外的文本會對其他用戶有很大的幫助。 –

+0

這是@ unutbu的答案更簡潔的版本。這是目前建議的最好的代碼,多一點解釋應該是被接受的答案。 – Quantum7

-2

你可以使用PIL.ImageDraw.Draw.multiline_text()

draw.multiline_text((WIDTH, HEIGHT), TEXT, fill=FOREGROUND, font=font) 

你甚至使用相同的名稱PARAM設置spacingalign

+0

不行,我只是試了一下。你能詳細說明用例嗎?我把一個非常長的字符串作爲'text'傳遞給它,並且它沒有換行到下一行。 –

+0

@HassanBaig你在絃樂中使用了什麼?例如:「Lorem Ipsum簡直就是虛擬\ n印刷和排版行業的文本。」 –

+0

文本來自用戶輸入,因此它們不使用中斷來指定下一行。我必須自己處理溢出。 –

3

被接受的答案在不測量字體的情況下包裝文本(最多40個字符,無論字體大小和文本框寬度是多少),所以結果只是近似值,並且可能很容易過滿或未滿。

下面是一個簡單的庫,它正確地解決了這個問題: https://gist.github.com/turicas/1455973

+0

這是最好的答案。我們應該嘗試改變接受的答案,因爲它在6年前被接受。 –