Search code examples
pythonpython-3.ximagepython-imaging-libraryword-wrap

Dynamically select the Text Message Size and write in image file (align = justify)


I have a code which collect text message from internet. The message size varies from 20-500 words. I want to write the text in image files with following condition:

  1. Image size should dynamically vary as per string size and written center justify.
  2. Image Background should be black.
  3. Test color should be random (to be picked from color list file)
  4. Test font should be random (to be picked from font list file)

I have written this code but could not get the desired result.

from PIL import Image, ImageDraw, ImageFont
import textwrap

font_list = []
color_list = []

astr = 'NRB Bearing Limited has informed the Exchange regarding Pursuant to Regulation 44(3) of the Listing Regulations, we enclose herewith the following in respect of the 54th Annual General Meeting (AGM) of the Company held on Friday, August 9, 2019 at 3:30 p.m.; at the M. C. Ghia Hall, Dubash Marg, Mumbai 400 001.1. Disclosure of the voting results of the businesses transacted at the AGM as required under Regulation 44(3) of the SEBI Listing Regulations.2. Report of the scrutinizer dated August 10, 2019, pursuant to Section 108 of the Companies Act, 2013.We request you to kindly take the same on record'
para = textwrap.wrap(astr, width=100)

MAX_W, MAX_H = 1200, 600
im = Image.new('RGB', (MAX_W, MAX_H), (0, 0, 0, 0))
draw = ImageDraw.Draw(im)
font = ImageFont.truetype('C://Users//Alegreya//Alegreya-RegularItalic.ttf', 18)

current_h, pad = 100, 20
for line in para:
    w, h = draw.textsize(line, font=font)
    draw.text(((MAX_W - w) / 2, current_h), line, font=font)
    current_h += h + pad

im.save('C://Users//greeting_card.png')

Solution

  • ImageDraw.text handles multi-lined text with consideration of spacing etc.

    from PIL import Image, ImageDraw, ImageFont
    import textwrap
    import random
    
    font_list = ['arial', 'calibri', ...]
    color_list = ['red', 'blue', ...]
    
    astr = 'NRB Bearing Limited has informed the Exchange regarding Pursuant to Regulation 44(3) of the Listing Regulations ...'
    para = textwrap.wrap(astr, width=100)
    para = '\n'.join(para)
    
    MAX_W, MAX_H = 1200, 600
    im = Image.new('RGB', (MAX_W, MAX_H), (0, 0, 0, 0))
    draw = ImageDraw.Draw(im)
    
    # randomly pick a font
    _idx = random.randint(0, len(font_list)-1)
    font_name = font_list[_idx]
    font = ImageFont.truetype(font_name, 18)
    # pick a color
    _idx = random.randint(0, len(color_list )-1)
    color = color_list[_idx]
    
    current_h = 100
    text_width, text_height = draw.textsize(para, font=font)
    
    draw.text(((MAX_W - text_width) / 2, current_h), para, font=font, fill=color,  align='center')
    
    im.save('C://Users//greeting_card.png')