Python, PIL; Text to Image and fonts - python

I have an issue with writing text to an image under Python and PIL -
I'm able to write text to a png file, though not bold text. Could anyone provide an example of how to achieve this?
I thought the easiest solution may be was use a bold-variant of a text, but I'm unable to see anything in the Windows/font folder that supplies this - does this mean font types have a 'bold attribute' that is T/F?:
Code I'm using:
import PIL
from PIL import ImageFont
from PIL import Image
from PIL import ImageDraw
# font = ImageFont.truetype("Arial-Bold.ttf",14)
font = ImageFont.truetype("Arial.ttf",14)
img=Image.new("RGBA", (500,250),(255,255,255))
draw = ImageDraw.Draw(img)
draw.text((0, 0),"This is a test",(0,0,0),font=font)
draw = ImageDraw.Draw(img)
img.save("a_test.png")

A simple way to do it:
font = ImageFont.load_default().font
Also you can do a google search for 'verdana.ttf' and download it put it in the same directory as the python file:
Then add it like this:
font = ImageFont.truetype("Verdana.ttf",14)

You aren't looking at actual font files in the control panel (explorer magically turns into the font viewer control panel when in the Windows/fonts folder as well), they are grouped by family for your convenience. Double click the family to see the fonts in the family:
Then right-click and choose properties to find the file name:

Related

How to use google font in tkinter

Is There any way to use google custom fonts in Tkinter Application.
I have google Font zip file from google font and I want to use that in my tkinter application.
I've came to the same problem, unfortunately it doesn't seem to be possible to use custom fonts in traditional way anyways.
But I came to a workaround by making a image with that text onto it.
def create_text_image(self, text, color_rgba_code_tuple):
fnt = Enums.ImageFont.truetype(Enums.FONT_DEFAULT, Enums.FONT_SIZE)
text_width, text_height = fnt.getsize(text)
img = Enums.Image.new('RGBA', (text_width,text_height))
d = Enums.ImageDraw.Draw(img)
d.text((0,0), text, font=fnt,fill=color_rgba_code_tuple)
img.save(Enums.FONT_TEMPORARY_IMAGE_PATH)
return Enums.PhotoImage(file=Enums.FONT_TEMPORARY_IMAGE_PATH)
Imports
from PIL import Image, ImageDraw, ImageFont, ImageTk
Explanation
You need to pass in your text and rgba tuple into the function; so, something like (255,255,255,255) for white text.
And then simply add that image that the function returns to a list, and use it in wherever place you want (like Canvas for example).
Hope this is clear.

How to add words on a picture and bold one of them using Pillow in Python?

I add text on the image using PIL library in Python. How can I bold one word in a sentence? Let's say I want to write in the picture: "This is an example sentence".
Currently, you can't bold, underline, italicize etc. certain parts of a sentence. You can use multiple separate .text() commands and change their x-y coordinates to make it look like one sentence. To bold text, you can use a bolded text font in a font family, and use that font for a .text() command. In the example below, I used the Arial and the Arial Bold font. I am on a windows machine, so the file paths will be different on Linux or Mac.
Code:
#import statements
import PIL
import PIL.Image as Image
import PIL.ImageDraw as ImageDraw
import PIL.ImageFont as ImageFont
#save fonts
font_fname = '/fonts/Arial/arial.ttf'
font_fname_bold = '/fonts/Arial/arialbd.ttf'
font_size = 25
#regular font
font = ImageFont.truetype(font_fname, font_size)
#bolded font
font_bold = ImageFont.truetype(font_fname_bold, font_size)
#Open test image. Make sure it is in the same working directory!
with Image.open("test.jpg") as img:
#Create object to draw on
draw = ImageDraw.Draw(img)
#Add text
draw.text(xy=(10,10),text="Gardens have ",font=font)
draw.text(xy=(175,10),text="many",font=font_bold)
draw.text(xy=(240,10),text=" plants and flowers",font=font)
#Display new image
img.show()
Test image:
https://i.stack.imgur.com/zU75J.jpg

Rendering Emoji with PIL

I am trying to make images out of tweets, however some of them contain Emojis. I am using PIL to render my images and the Symbola font.
The text is in unicode utf-8 encoding and the Symbola font does include the emojis. Here is an abridged version of the code:
from PIL import Image, ImageFont, ImageDraw
text = u"\U0001f300" #CYCLONE emoji
image = Image.new("RGBA", (100,100), (255,255,255))
font = ImageFont.truetype("Symbola.ttf", 60, encoding='unic')
draw = ImageDraw.Draw(image)
draw.text((0,0), text, (0,0,0), font=font)
image.save("Test.png")
image.show()
This just renders and image with two rectangles instead of the emoji
Would appreciate any help or ideas.
Thanks!
EDIT: As falsetru pointed out, this code does run in Ubuntu, however it doesn't run on Windows or on Mac. Any ideas?
If the symbol CYCLONE u"\U0001f300" (I download a Symbola.tff from web) then is a very simple to use with PIL:
from PIL import Image, ImageDraw, ImageFont, ImageFilter
#configuration
font_size=36
width=500
height=100
back_ground_color=(255,255,255)
font_size=36
font_color=(0,0,0)
unicode_text =u"\U0001f300"
im = Image.new ( "RGB", (width,height), back_ground_color )
draw = ImageDraw.Draw ( im )
unicode_font = ImageFont.truetype("Symbola.ttf", font_size)
draw.text ( (10,10), unicode_text, font=unicode_font, fill=font_color )
im.show()
Take a look at this
There was a bug in Pillow, see #1774 or #3777. This should now be fixed in version 6.1 of Pillow with PR#3780, but only for Python 3.x.
If you are looking to write symbols with your original font, you can do this by merging your font with Symbola.ttf or any emojis font. You can merge the two fonts using fontforge (https://fontforge.org/).
start fontforge, open up your main font,
Click menu: element->merge fonts and choose your emoji font (Symbola.ttf).
answer no for any popup dialog.
optionally change your new font's name: element->font info.
finally go to file->generate fonts when done and save it as ttf (TrueType).
Now, you can use your generated font to draw text with emojis!

View a document TKinter

I am new to TKinter and cant seem to find any examples on how to view a document in a window. What I am trying to accomplish is that when selecting a PDF or TIF it will open the file and show the first page in a window using TKinter. Is this possible?
A long time has passed since this question was posted but, for those still looking for a solution, here's one I've found :
https://github.com/rk700/PyMuPDF/wiki/Demo:-GUI-script-to-display-a-PDF-using-wxPython-or-Tkinter
Basically, it uses PyMuPDF, a python binding for MuPDF. MuPDF is a lightweight document viewer capable of displaying a few file formats, such as pdf and epub.
I quote the code used for TKinter:
This demo can easily be adopted to Tkinter. You need the imports
from Tkinter import Tk, Canvas, Frame, BOTH, NW
from PIL import Image, ImageTk
and do the following to display each PDF page image:
#-----------------------------------------------------------------
# MuPDF code
#-----------------------------------------------------------------
pix = doc.getPagePixmap(pno - 1) # create pixmap for a page
#-----------------------------------------------------------------
# Tkinter code
#-----------------------------------------------------------------
self.img = Image.frombytes("RGBA",
[pix.width, pix.height],
str(pix.samples))
self.photo = ImageTk.PhotoImage(self.img)
canvas = Canvas(self, width=self.img.size[0]+20,
height=self.img.size[1]+20)
canvas.create_image(10, 10, anchor=NW, image=self.photo)
canvas.pack(fill=BOTH, expand=1)
No, it is not possible to show a TIF or PDF in a Tkinter window. Your main options are to show plain text, and to show images (.gif with plain Tkinter, other formats if you include PIL - the python imaging library).
Nothing is impossible my friend!
Try using snippets from this:
http://nedbatchelder.com/blog/200712/extracting_jpgs_from_pdfs.html
to convert the pdf to an image.
I would then display the image on a label using PIL and Tkinter.
And I think Tif files should display on a label without problems IIRC.
The following code uses the old library pypdfocr (I had to modify it to work with Python 3) and Ghostscript (Ghostscript needs to be installed outside of Python and so isn't ideal for software to be distributed) to convert each of the PDF's pages into an image that can then be opened by PIL. In the sense that it uses very old libraries and packages, DrD's answer is probably more appropriate.
import glob
import PIL.Image
import PIL.ImageTk
import pypdfocr.pypdfocr_gs as pdfImg
files = glob.glob(pdfImg.PyGs({}).make_img_from_pdf(file_name)[1])
pages = [PIL.ImageTk.PhotoImage(PIL.Image.open(file)) for file in files]

How can I find out why PIL isn't drawing the font correctly?

Here's the code I'm using:
from PIL import Image
import ImageFont, ImageDraw
import sys
import pdb
img = Image.new("RGBA",(300,300))
draw = ImageDraw.Draw(img)
font = ImageFont.truetype(sys.argv[1],30)
draw.text((0,100),"world",font=font,fill="red")
del draw
img.save(sys.argv[2],"PNG")
and here's the image that results:
img http://www.freeimagehosting.net/image.php?976a0d3eaa.png ( for some reason, I can't make it show on SO, so the link is http://www.freeimagehosting.net/image.php?976a0d3eaa.png )
The thing is, I don't understand why it isn't drawing the font correctly? I should be able to read the word "world" off of it. It's like the picture's been cut in half or something. Does anyone have any clue?
EDIT: after balpha's comment, I decided to try another font. I'm only interested in ttf fonts, so I tried with another one, and it worked. This is kind of strange. The original font I tried to run this with is Beautiful ES. I'm curious if you guys can reproduce the same image on your computers, and if you happen to know the reason for why that is.
PIL uses the freetype2 library, so most possibly it is an issue with the font file; for example, it could have bad metrics defined (e.g see the OS/2 related ones opening the font with FontForge).

Categories