2011-10-08 7 views
23

Tôi cố gắng thêm văn bản ở cuối hình ảnh và thực sự tôi đã thực hiện nó, nhưng trong trường hợp văn bản của tôi dài hơn thì chiều rộng hình ảnh được cắt từ cả hai bên, để đơn giản hóa như văn bản nằm trong nhiều dòng nếu văn bản dài hơn chiều rộng hình ảnh. Đây là mã của tôi:python PIL vẽ văn bản nhiều dòng trên hình ảnh

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') 

Trả lời

33

Bạn có thể sử dụng để phá vỡ textwrap.wraptext vào một danh sách các chuỗi, dài mỗi tối đa là width ký tự:

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

Cảm ơn rất nhiều! chỉ cần sao chép và dán và nó hoạt động như một nét duyên dáng. Bạn là tốt nhất :) – user985541

+0

'40' đại diện cho cái gì? – User

+1

@Người dùng '40' đại diện cho các ký tự tối đa. Có nghĩa là nó sẽ cho phép tối đa hoặc 40 ký tự trước khi nó kết thúc tốt đẹp với một dòng mới. Nhưng nếu một từ là 10 ký tự và sau đó tiếp theo là 31 ký tự, nó sẽ bọc ngay sau từ đầu tiên vì nó không thể phù hợp với từ đầu tiên và thứ hai trên dòng. – teewuane

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

Chào mừng bạn đến với SO! Bạn có thể vui lòng giải thích cách giải quyết câu hỏi này không? Một chút văn bản bổ sung sẽ đi một chặng đường dài cho những người dùng khác. –

+0

Đây là phiên bản ngắn gọn hơn về câu trả lời của @ unutbu. Đó là mã tốt nhất hiện được đề xuất, và với một chút giải thích hơn phải là câu trả lời được chấp nhận. – Quantum7

-2

Bạn có thể sử dụng PIL.ImageDraw.Draw.multiline_text().

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

Bạn thậm chí đặt spacing hoặc align sử dụng cùng tên param.

+0

Không hoạt động, tôi đã thử nó. Bạn có thể xây dựng trường hợp sử dụng không? Tôi đã vượt qua một chuỗi dài thực sự với điều này như là 'văn bản', và nó không được bọc vào dòng tiếp theo. –

+0

@HassanBaig bạn có sử dụng ngắt trong chuỗi không? Ví dụ: "Lorem Ipsum chỉ đơn giản là giả \ n văn bản của ngành in \ n và sắp chữ". –

+0

Văn bản đến từ đầu vào của người dùng và do đó chúng không sử dụng ngắt để chỉ định dòng tiếp theo. Tôi sẽ phải tự xử lý tràn. –

3

Câu trả lời được chấp nhận bao bọc văn bản mà không cần đo phông chữ (tối đa 40 ký tự, bất kể kích thước phông chữ và chiều rộng hộp), vì vậy kết quả chỉ gần đúng và có thể dễ dàng chèn lấp hoặc lấp đầy hộp.

Đây là một thư viện đơn giản mà giải quyết vấn đề một cách chính xác: https://gist.github.com/turicas/1455973

+0

đây là câu trả lời hay nhất. Chúng ta nên cố gắng thay đổi câu trả lời được chấp nhận bởi vì nó đã được chấp nhận cách đây 6 năm .. –