2009-06-14 41 views
7

Viết văn bản đơn giản trên hình ảnh bằng PIL thật dễ dàng.Viết văn bản với dấu phụ ("nikud", nhãn hiệu) bằng PIL (Thư viện ảnh Python)

draw = ImageDraw.Draw(img) 
draw.text((10, y), text2, font=font, fill=forecolor) 

Tuy nhiên, khi tôi cố gắng viết dấu câu tiếng Do Thái (gọi là "nikud" hoặc ניקוד), các ký tự không trùng lặp như chúng cần. (Tôi đoán câu hỏi này cũng có liên quan đến tiếng Ả Rập và các ngôn ngữ tương tự khác.)

Trên môi trường hỗ trợ, hai từ này chiếm cùng một không gian/chiều rộng (ví dụ bên dưới tùy thuộc vào hệ thống của bạn, do đó hình ảnh):

סֶפֶר ספר

Tuy nhiên khi vẽ văn bản với PIL tôi nhận được:

ס ֶ פ ֶ ר

từ thư viện có lẽ không tuân theo quy tắc kerning (?).

Có thể có ký tự và dấu chấm câu tiếng Do Thái chiếm cùng không gian/chiều rộng mà không cần viết vị trí ký tự theo cách thủ công không?

image - nikud and letter spacing http://tinypic.com/r/jglhc5/5

ảnh url: http://tinypic.com/r/jglhc5/5

Trả lời

2

buồn cười, sau 5 năm, và với sự giúp đỡ to lớn fron @ Nasser Al-Wohaibi, tôi nhận ra cách thực hiện:

Đảo ngược văn bản bằng thuật toán BIDI là cần thiết.

# -*- coding: utf-8 -*- 
from bidi.algorithm import get_display 
import PIL.Image, PIL.ImageFont, PIL.ImageDraw 
img= PIL.Image.new("L", (400, 200)) 
draw = PIL.ImageDraw.Draw(img) 
font = PIL.ImageFont.truetype(r"c:\windows\fonts\arial.ttf", 30) 
t1 = u'סֶפֶר ספר!' 
draw.text((10,10), 'before BiDi :' + t1, fill=255, font=font) 

t2 = get_display(t1)  # <--- here's the magic <--- 
draw.text((10,50), 'after BiDi: ' + t2, fill=220, font=font) 

img.save('bidi-test.png') 

@ câu trả lời Nasser có giá trị bổ sung mà có lẽ chỉ có liên quan đến văn bản arabic (các ký tự trong hình dạng thay đổi arabic và kết nối-ness dựa trên chữ neiboring của họ, trong hebrew tất cả các chữ riêng biệt), vì vậy chỉ một phần bidi có liên quan cho câu hỏi này.

trong kết quả mẫu, dòng thứ 2 là biểu mẫu chính xác và định vị nhãn hiệu chính xác.

before and after bidi

cảm ơn bạn @tzot để được giúp đỡ + đoạn mã

một Propos:

mẫu của hành vi phông chữ khác nhau với Hebrew "nikud". Không phải tất cả các phông chữ đều hoạt động giống nhau: sample PIL written, bidi hebrew text, with nikud, in different fonts

+0

Xin chào, tôi đã có ** [vấn đề tương tự bằng cách sử dụng Pillow] (http://stackoverflow.com/questions/41271620/the-nikud-are-not-aligned -properly-while-drawing-text-in-hebrew-using-pil-pytho) **. Bạn đã bao giờ tìm ra một sửa chữa để có được nikud liên kết đúng bất kể phông chữ? – maltman

0

Trông với tôi rằng trường hợp này là khá đơn giản. Bạn có thể sử dụng font True Type và sử dụng

Dưới đây là ví dụ: True type fonts for PIL

Ở đây bạn có thể tìm thấy Hebrew True Type fonts: Hebrew true type fonts

Chúc may mắn hay như chúng ta nói bằng tiếng Hebrew - Mazal' Tov.

+0

Cảm ơn bạn đã trả lời nhưng bạn chưa trả lời câu hỏi. Như tôi đã viết - Tôi biết cách viết TTF và tôi đã có phông chữ TTF. –

2

Bạn đang làm việc với hệ thống nào? Nó hoạt động với tôi trên hệ thống Gentoo của tôi; thứ tự của các chữ cái được đảo ngược (tôi chỉ cần sao chép-dán từ câu hỏi của bạn), mà dường như chính xác với tôi mặc dù tôi không biết nhiều về ngôn ngữ RTL.

Python 2.5.4 (r254:67916, May 31 2009, 16:56:01) 
[GCC 4.3.3] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import Image as I, ImageFont as IF, ImageDraw as ID 
>>> t= u"סֶפֶר ספר" 
>>> t 
u'\u05e1\u05b6\u05e4\u05b6\u05e8 \u05e1\u05e4\u05e8' 
>>> i= I.new("L", (200, 200)) 
>>> d= ID.Draw(i) 
>>> f= IF.truetype("/usr/share/fonts/dejavu/DejaVuSans.ttf", 20) 
>>> d1.text((100, 40), t, fill=255, font=f) 
>>> i.save("/tmp/dummy.png", optimize=1) 

sản xuất:

the example text rendered as white on black http://i39.tinypic.com/2j9jxf.png

EDIT: Tôi nên nói rằng việc sử dụng phông chữ Deja Vu Sans Không phải ngẫu nhiên; mặc dù tôi không thích nó nhiều lắm (nhưng tôi vẫn thấy glyphs tốt hơn Arial), nó có thể đọc được, nó đã mở rộng phạm vi phủ sóng Unicode, và nó có vẻ hoạt động tốt hơn với nhiều ứng dụng không phải MS hơn Arial Unicode MS.

+0

Bạn đã không thực sự trả lời, nhưng bạn giúp nhìn thấy lỗi: Chỉ DejaVuSans.ttf và Lucidaxxx.ttf hành xử đúng theo PIL! Tất cả các tệp TTF còn lại của tôi đều tạo ra kết quả sai (nhưng chúng hoạt động độc đáo bên ngoài PIL) Bạn có thể thử các phông chữ khác, ví dụ: Arial.ttf –

+1

Phông chữ TrueType (hoặc phông chữ OpenType) không nhất thiết có nghĩa là phông chữ hoàn chỉnh và hữu ích trong tất cả các ứng dụng. Michael Kaplan (làm việc cho MS hiện tại và rất liên quan đến các vấn đề Unicode) gọi ArialUni là "phông chữ MS Office", không phải là "phông chữ hệ điều hành", bất cứ điều gì ông có nghĩa là bởi nó, ở đây: http://blogs.msdn.com/michkap/ Lưu trữ/2007/07/15/3890144.aspx – tzot

8

Đối với Ả Rập dấu: Python + Wand (Python Lib) + arabic_reshaper (Python Lib) + bidi.algorithme (Python Lib).Điều tương tự cũng áp dụng cho PIL/Gối, bạn cần phải sử dụng arabic_reshaperbidi.algorithm và vượt qua các văn bản được tạo ra để draw.text((10, 25), artext, font=font):

from wand.image import Image as wImage 
from wand.display import display as wdiplay 
from wand.drawing import Drawing 
from wand.color import Color 
import arabic_reshaper 
from bidi.algorithm import get_display 

reshaped_text = arabic_reshaper.reshape(u'لغةٌ عربيّة') 
artext = get_display(reshaped_text) 

fonts = ['C:\\Users\\PATH\\TO\\FONT\\Thabit-0.02\\DroidNaskh-Bold.ttf', 
     'C:\\Users\\PATH\\TO\\FONT\\Thabit-0.02\\Thabit.ttf', 
     'C:\\Users\\PATH\\TO\\FONT\\Thabit-0.02\\Thabit-Bold-Oblique.ttf', 
     'C:\\Users\\PATH\\TO\\FONT\\Thabit-0.02\\Thabit-Bold.ttf', 
     'C:\\Users\\PATH\\TO\\FONT\\Thabit-0.02\\Thabit-Oblique.ttf', 
     'C:\\Users\\PATH\\TO\\FONT\\Thabit-0.02\\majalla.ttf',   
     'C:\\Users\\PATH\\TO\\FONT\\Thabit-0.02\\majallab.ttf', 

     ] 
draw = Drawing() 
img = wImage(width=1200,height=(len(fonts)+2)*60,background=Color('#ffffff')) 
#draw.fill_color(Color('#000000')) 
draw.text_alignment = 'right'; 
draw.text_antialias = True 
draw.text_encoding = 'utf-8' 
#draw.text_interline_spacing = 1 
#draw.text_interword_spacing = 15.0 
draw.text_kerning = 0.0 
for i in range(len(fonts)): 
    font = fonts[i] 
    draw.font = font 
    draw.font_size = 40 
    draw.text(img.width/2, 40+(i*60),artext) 
    print draw.get_font_metrics(img,artext) 
    draw(img) 
draw.text(img.width/2, 40+((i+1)*60),u'ناصر test') 
draw(img) 
img.save(filename='C:\\PATH\\OUTPUT\\arabictest.png'.format(r)) 
wdiplay(img) 

Arabic typography in images

Các vấn đề liên quan