How to convert a string to an image?
Asked Answered
E

2

45

I started to learn python a week ago and want to write a small program that converts a email to a image (.png) so that it can be shared on forums without risking to get lots of spam mails.

It seems like the python standard library doesn't contain a module that can do that but I've found out that there's a PIL module for it (PIL.ImageDraw).

My problem is that I can't seem to get it working.

So basically my questions are:

  1. How to draw a text onto a image.
  2. How to create a blank (white) image
  3. Is there a way to do this without actually creating a file so that I can show it in a GUI before saving it?

Current Code:

import Image
import ImageDraw
import ImageFont

def getSize(txt, font):
    testImg = Image.new('RGB', (1, 1))
    testDraw = ImageDraw.Draw(testImg)
    return testDraw.textsize(txt, font)

if __name__ == '__main__':

    fontname = "Arial.ttf"
    fontsize = 11   
    text = "[email protected]"
    
    colorText = "black"
    colorOutline = "red"
    colorBackground = "white"


    font = ImageFont.truetype(fontname, fontsize)
    width, height = getSize(text, font)
    img = Image.new('RGB', (width+4, height+4), colorBackground)
    d = ImageDraw.Draw(img)
    d.text((2, height/2), text, fill=colorText, font=font)
    d.rectangle((0, 0, width+3, height+3), outline=colorOutline)
    
    img.save("D:/image.png")
Eleanoraeleanore answered 25/7, 2013 at 11:4 Comment(5)
Could you show us what you have already tried and where it is going wrong?Agone
i don't really have anything yet. The problem is that i can't find a real doc for the ImageDraw module so i don't know how to use itEleanoraeleanore
related: python PIL draw multiline text on imageAvantgarde
@user1743130 it seems that PIL documentation from pythonware.com got removed. You could use the documentation which comes with python-imaging module though.Pyle
The latest documentation for the pillow fork of PIL can be found here. pillow supports Python 3, unlike PIL itself.Indoiranian
P
51
  1. use ImageDraw.text - but it doesn't do any formating, it just prints string at the given location

    img = Image.new('RGB', (200, 100))
    d = ImageDraw.Draw(img)
    d.text((20, 20), 'Hello', fill=(255, 0, 0))
    

    to find out the text size:

    text_width, text_height = d.textsize('Hello')
    
  2. When creating image, add an aditional argument with the required color (white):

    img = Image.new('RGB', (200, 100), (255, 255, 255))
    
  3. until you save the image with Image.save method, there would be no file. Then it's only a matter of a proper transformation to put it into your GUI's format for display. This can be done by encoding the image into an in-memory image file:

    import cStringIO
    s = cStringIO.StringIO()
    img.save(s, 'png')
    in_memory_file = s.getvalue()
    

    or if you use python3:

    import io
    s = io.BytesIO()
    img.save(s, 'png')
    in_memory_file = s.getvalue()
    

    this can be then send to GUI. Or you can send direct raw bitmap data:

    raw_img_data = img.tostring()
    
Pyle answered 25/7, 2013 at 11:23 Comment(7)
is there a way to find out wich size the image has to be?Eleanoraeleanore
@user1743130 edited - but try to look for the documentation. Or you can just run python, write import ImageDraw and then help(ImageDraw), help(ImageDraw.textsize), etc.Pyle
textsize only seems to change the size of the text but i want to know how big the image has to be so that the text fits in (in pixels)Eleanoraeleanore
@user1743130 textsize doesn't change anything, it tells you how big the text will be. So you can just create one "scrap" image to test for needed size and based on that, you'll create the real imagePyle
why does the code in my question works fine for fontsize = 400 but if fontsize is set to 11 the text isn't centered and the image height is too high?Eleanoraeleanore
It didn't work for me. Now, with Python 3.7, it needs to use from io import BytesIO and replace cStringIO.StringIO() with BytesIOSchizogenesis
@Schizogenesis - well, it's from 2013 - but you're right, I'll add it to the answer, thanksPyle
C
10

The first 3 lines are not complete, when I'm not wrong. The correct code would be:

from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
Carcinoma answered 12/9, 2019 at 13:2 Comment(2)
This is necessary in modern Pillow package - in old, original PIL, import Image* was valid, there was no PIL subpackage.Pyle
shorter code from PIL import Image, ImageDraw, ImageFontCoadjutor

© 2022 - 2024 — McMap. All rights reserved.