4

I'm trying to figure out a way to automate the formatting of a png to add titles subtitles and a footer bar with a logo image and source. I'd like to do this image formatting with python since I'm the most familiar with that language. I'm looking for some direction here on what modules would be good to use for something like this? Ideally the process would look something like this for a user of the script.

1) User would have a png image that looked something like this:

enter image description here

2) User would launch the script:

python autochart_formatting.py

3) Script would prompt the user for the following information:

  • Enter chart title:
  • Enter chart subtitle:
  • Enter source:
  • Survey name:
  • Sample n=:
  • Enter the path to chart png you want formatted:
  • Enter the path where you want the formatted image saved:

3) With that information the png would be formatted with to look something like this:

enter image description here

2 Answers 2

1

Pillow (the maintained successor to PIL: Python Imaging Library) can handle exactly what you want.

You can extend your image and place the text after retrieving user input. Here is an example for adding the title:

from PIL import Image, ImageFont, ImageDraw

img = Image.open('my_chart.png')
w,h= img.size

# put pixels into 2D array for ease of use
data = list(img.getdata())
xy_data = []
for y in xrange(h):
    temp = []
    for x in xrange(w):
        temp.append(data[y*w + x])
    xy_data.append(temp)

# get the title
title = raw_input("Title:")

# load the font
font_size = 20
font = ImageFont.truetype("/path/to/font.ttf",font_size)

#  Get the required height for you images
height_needed = font.getsize(title)[1] + 2  # 2 px for padding

# get the upperleft pixel to match color
bg = xy_data[0][0]

# add rows to the data to prepare for the text
xy_data = [[bg]*w for i in range(height_needed+5)] + xy_data  # +5 for more padding

# resize image
img = img.resize((w,h+height_needed+5))

# convert data back to 1D array
data = []
for line in xy_data:
    data += line

# put the image back in the data
img.putdata(data)

# get the ImageDraw item for this image
draw = ImageDraw.Draw(img)

# draw the text
draw.text((5,0),title,font=font,fill=(0,0,0))  # fill is black

img.save('titled_plot.png')
Sign up to request clarification or add additional context in comments.

11 Comments

Seems to be some issues with this script. I think h and w through the script are defined as height and width to begin with
@moku ah true, sorry, just change them to w,h I will update my answer.
I changed them and it throwing a error about the ImageFont.py file:
Traceback (most recent call last): File "HubbleFormatter.py", line 20, in <module> font = ImageFont.truetype("/Users/kyle/Destop/GothamFonts/GOTHMBOK.ttf",font_size) File "/usr/local/lib/python2.7/site-packages/PIL/ImageFont.py", line 262, in truetype return FreeTypeFont(font, size, index, encoding) File "/usr/local/lib/python2.7/site-packages/PIL/ImageFont.py", line 142, in init self.font = core.getfont(font, size, index, encoding) IOError: cannot open resource
@moku You need to specify a font file, I do not know your computer, so I could not put a real path to a font file there.
|
0

This is all well within the capabilities of Pillow (a fork of the Python Imaging Library that is still being maintained).

You could also do this with matplotlib if you don't want to roll your own graphing code. It would give you slightly less flexibility in how your graph is formatted, but it would be quicker to create.

4 Comments

Great I will check out Pillow. Matplotlib is a possibility but not everyone has the skills for that. Some chart images will come from Excel and be saved as a png and need to be formatted this way. How would Pillow deal with sizing differences from the imported pngs? Would that be a hassle or should there just be like 3 standard image sizes that it can format to simplify things?
I see - I didn't understand from your question that you are just modifying charts - I thought you were creating them from scratch. In that case, yes, you will need Pillow, not matplotlib. Pillow is a general image processing module, so it's very flexible.
Pillow is perfectly capable of resizing your images, if that's what you mean. Or if you're asking how you can add titles if the charts are different sizes...I can't help with that unless you describe the constraints more specifically.
True I think I will just need to cross that bridge when I get there and just dive into pillow and see what it can do!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.