2012-08-17 7 views
5

mam kilka zdjęć znak wodny za pomocą PIL i mam kłopoty z czytaniem część tekstu (czarny tekst na ciemnym tle). Nie mogę zmienić koloru tekstu, ponieważ mam szeroki wachlarz kolorów tła. Czy istnieje jakiś sposób dodania efektu halo wokół tekstu?Tworzenie halo wokół tekstu w Pythonie za pomocą PIL?

Na przykład: http://i.imgur.com/WYxSU.jpg Tekst na dole jest tym, co mam, a górny tekst jest tym, co mam nadzieję uzyskać (kolory na bok). Po prostu potrzebuję cienkiego konturu wokół tekstu. Jakieś pomysły? Mogę przesłać kod, jeśli naprawdę uważasz, że to coś zmieni, ale jest to zwykłe polecenie PIL ImageDraw.Draw. Dzięki!

+1

wydrukować tekst trzy razy. Pierwsze dwa z kolorem zarys i przesunięciami (-1, -1) oraz (1, 1), a trzeci z pierwotnego koloru w pozycji wyjściowej. – Matthias

+2

http://mail.python.org/pipermail/image-sig/2009-May/005681.html http://stackoverflow.com/a/8050556/442650 –

+0

PIL.ImageDraw ma opcję "konspektu", ale nie dotyczy tekstu. –

Odpowiedz

7

Jeśli nie dbają o prędkości zbyt wiele, można to zrobić za pomocą skład: tekst

  1. rysować koloru halo na pustym RGBA obrazu
  2. plama to
  3. wyciągnąć go ponownie kolor tekstu
  4. inwertowany ten obraz, aby uzyskać skład maskować
  5. „scalić” z oryginalnego obrazu

Na przykład:

import sys 
import Image, ImageChops, ImageDraw, ImageFont, ImageFilter 

def draw_text_with_halo(img, position, text, font, col, halo_col): 
    halo = Image.new('RGBA', img.size, (0, 0, 0, 0)) 
    ImageDraw.Draw(halo).text(position, text, font = font, fill = halo_col) 
    blurred_halo = halo.filter(ImageFilter.BLUR) 
    ImageDraw.Draw(blurred_halo).text(position, text, font = font, fill = col) 
    return Image.composite(img, blurred_halo, ImageChops.invert(blurred_halo)) 

if __name__ == '__main__': 
    i = Image.open(sys.argv[1]) 
    font = ImageFont.load_default() 
    txt = 'Example 1234' 
    text_col = (0, 255, 0) # bright green 
    halo_col = (0, 0, 0) # black 
    i2 = draw_text_with_halo(i, (20, 20), txt, font, text_col, halo_col) 
    i2.save('halo.png') 

Ma wiele zalet:

  • efektem jest gładka i wygląda ładnie
  • można wybrać inny filtr zamiast BLUR dostać inny "halo"
  • działa nawet przy bardzo dużych czcionek i nadal wygląda świetnie

Aby uzyskać grubsze halo, można użyć filtra tak:

kernel = [ 
    0, 1, 2, 1, 0, 
    1, 2, 4, 2, 1, 
    2, 4, 8, 4, 1, 
    1, 2, 4, 2, 1, 
    0, 1, 2, 1, 0] 
kernelsum = sum(kernel) 
myfilter = ImageFilter.Kernel((5, 5), kernel, scale = 0.1 * sum(kernel)) 
blurred_halo = halo.filter(myfilter) 

Część scale = 0.1 * sum(kernel) sprawia aureolę grubszą (małe wartości) lub ściemniacza (duże wartości).

+0

Myślę, że właściwy kontur wyglądałby lepiej w tym przypadku, jak w przykładzie w pytaniu, ale jest to właściwy sposób generowania "halo". Jedynym minusem jest to, że im szerszy halo, tym ściemniacz dostaje. Jestem trochę rozczarowany, że PIL nie daje prostszego sposobu łączenia obrazu RGBA z innym. –

+0

Fajne dzięki. Tylko jedno pytanie ... rozmycie jest bardzo rozmyte ... z czarnym tekstem i białym rozmyciem ... zamazanie w rzeczywistości okazuje się niewidoczne na czarnym tle. Jak możemy to wyostrzyć? Może to właśnie masz na myśli przez grubsze halo? – Jonny

+0

@ Jonny tak, to pewnie by tak było. Możesz też użyć innego filtru (zobacz: http://pillow.readthedocs.org/en/latest/reference/ImageFilter.html), graj z wartościami * scale * lub * offset * w http://pillow.readthedocs.org/en/latest/reference/ImageFilter.html#PIL.ImageFilter.Kernel –

Powiązane problemy