I'm watermarking some pictures using PIL and I'm having a hard time reading some of the text (black text on dark background). I can't just change text color since I've got a wide array of background colors. Is there any way to add a halo effect around the text?
For example: http://i.imgur.com/WYxSU.jpg The bottom text is what I've got, and the top text is what I'm hoping to get (colors aside). I really just need a thin outline around the text. Any ideas? I can upload some code if you really think it'll make a difference, but it's just a normal PIL ImageDraw.Draw command. Thanks!
If you don't care about speed too much, you can do it using composition:
RGBA
imageFor example:
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')
It has many advantages:
BLUR
to get different "halo"To get thicker halo, you may use filter like this:
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)
The part scale = 0.1 * sum(kernel)
makes the halo thicker (small values) or dimmer (big values).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With