PIL.ImageDraw.Draw(im, mode=None)
im: Image to work 
from PIL import Image, ImageDraw, ImageFont
path = "E:\\testing\\images\\cat.png" # existing image to open
img = Image.open(path)
Font family and size.
fnt = ImageFont.truetype("times.ttf", 140) # family with size
#fnt = ImageFont.truetype("arial.ttf", 140)
Full code to read image, add text and save in given path is here.
from PIL import Image, ImageDraw, ImageFont
path = "E:\\testing\\images\\cat.png" # existing image to open
path2 = "E:\\testing\\images\\cat2.png" # save the new image path
img = Image.open(path)
fnt = ImageFont.truetype("times.ttf", 140)
d1 = ImageDraw.Draw(img)
d1.text((80, 160), "plus2net", fill=(194, 61, 43),font=fnt)
img.show()
img.save(path2) # Save the image in new location or path


from PIL import Image, ImageDraw, ImageFont
path = "F:\\testing\\images\\certificate.png" # blank certificate
path2 = "F:\\testing\\images\\certificate_01.png" # final certificate
img = Image.open(path, mode="r")
# img.show()
img1 = ImageDraw.Draw(img) # create object to Draw
fnt1 = ImageFont.truetype("arial.ttf", 70) # font for Label text
fnt2 = ImageFont.truetype("arial.ttf", 50) # font for data text
fill1 = (39, 77, 113) # colour of the Label text
fill2 = (19, 119, 169) # colour of the data text
img1.text((280, 700), "Name :", fill=fill1, font=fnt1)
img1.text((550, 720), "plus2net", fill=fill2, font=fnt2)
img1.text((280, 800), "Grade :", fill=fill1, font=fnt1)
img1.text((550, 820), "B+", fill=fill2, font=fnt2)
img1.text((280, 900), "Class :", fill=fill1, font=fnt1)
img1.text((550, 920), "Five", fill=fill2, font=fnt2)
img.show()
img.save(path2) # Save the image in new location or path

from PIL import Image, ImageDraw, ImageFont
path = "E:\\testing\\images\\certificate_b.png" # blank certificate
path2 = "E:\\testing\\images\\certificate_12.png" # final certificate
img = Image.open(path, mode="r")
# img.show()
img1 = ImageDraw.Draw(img) # create object to Draw
fnt1 = ImageFont.truetype("arial.ttf", 70) # Font
fnt2 = ImageFont.truetype("arial.ttf", 50)
fill2 = (19, 119, 169) # colour used for data
l1=[12,'plus2net','Five',80] # List data to use for certificate
img1.text((570, 615), str(l1[0]), fill=fill2, font=fnt2)
img1.text((570, 720), l1[1], fill=fill2, font=fnt1)
img1.text((570, 870), l1[2], fill=fill2, font=fnt1)
img1.text((570, 1000), str(l1[3]), fill=fill2, font=fnt1)
img.show()
img.save(path2) # Save the image in new location or path

certificate_4.png
certificate_5.png
certificate_5.png
....
The path to store the certificates are created using above format and inside the for loop each time a new file name is created. str() is used to convert integer to string.
path2 = "E:\\testing\\images\\certificate_"+str(row[0])+".png"
We will connect to Database and execute the query.
from sqlalchemy import create_engine
my_conn = create_engine("mysql+mysqldb://root:pw@localhost/my_db")
execute the query and get all the records. Here we are using LIMIT query to get 5 records only. This can be increased to get more records.
l1=my_conn.execute("SELECT * FROM student limit 0,5")
Full code is here
from PIL import Image, ImageDraw, ImageFont
from sqlalchemy import create_engine
my_conn = create_engine("mysql+mysqldb://id:pw@localhost/my_db")
path = "E:\\testing\\images\\certificate_b.png" # blank certificate
fnt1 = ImageFont.truetype("arial.ttf", 70) # Font
fnt2 = ImageFont.truetype("arial.ttf", 50)
fill2 = (19, 119, 169) # colour used for data
l1=my_conn.execute("SELECT * FROM student limit 0,5")
for row in l1:
print(row )
img = Image.open(path, mode="r")
img1 = ImageDraw.Draw(img) # create object to Draw
path2 = "E:\\testing\\images\\certificate_"+str(row[0])+".png"
img1.text((570, 615), str(row[0]), fill=fill2, font=fnt2)
img1.text((570, 720), row[1], fill=fill2, font=fnt1)
img1.text((570, 870), row[2], fill=fill2, font=fnt1)
img1.text((570, 1000), str(row[3]), fill=fill2, font=fnt1)
img.show()
img.save(path2) # Save the image in new location or path
img = Image.new("RGBA", (width, height), color="#F1F1CC")
#img = Image.new("RGB", (width, height), color="#F1F1CC")
if img.mode == 'RGBA':
img = img.convert('RGB')
from PIL import Image, ImageDraw, ImageFont
path = "E:\\testing\\images\\arc1.pdf" # new pdf file to create
width, height = 400, 200
img = Image.new("RGBA", (width, height), color="#F1F1CC")
#img = Image.new("RGB", (width, height), color="#F1F1CC") # in RGB mode
if img.mode == 'RGBA': # Not required if image mode is RGB
img = img.convert('RGB')
img1 = ImageDraw.Draw(img) # create object to Draw
fnt = ImageFont.truetype("arial.ttf", 40)
img1.text((width-215,height-115), "Plus2net", fill=(194, 61, 43), font=fnt,anchor='ls')
#print(img1.text['anchor'].getvalue())
img.show()
img.save(path) # Save the image in new location or path
Here is the changes required in above certificate generation script to get all certificates in PDF format.
img = Image.open(path, mode="r")
if img.mode == 'RGBA':
img = img.convert('RGB')
img1 = ImageDraw.Draw(img) # create object to Draw
#path2 = "E:\\testing\\images\\certificate_"+str(row[0])+".png"
path2 = "E:\\testing\\images\\certificate_"+str(row[0])+".pdf"

from PIL import Image, ImageDraw, ImageFont
path = "F:\\testing\\images\\certificate_b.png" # blank certificate
path2 = "" # final certificate
img = Image.open(path, mode="r")
if img.mode == "RGBA":
img = img.convert("RGB")
# img.show()
img1 = ImageDraw.Draw(img) # create object to Draw
fnt1 = ImageFont.truetype("arial.ttf", 70) # Font
fnt2 = ImageFont.truetype("arial.ttf", 50)
fill2 = (19, 119, 169) # colour used for data
l1 = [12, "plus2net", "Five", 80] # List data for certificate
img1.text((570, 615), str(l1[0]), fill=fill2, font=fnt2)
img1.text((570, 720), l1[1], fill=fill2, font=fnt1)
img1.text((570, 870), l1[2], fill=fill2, font=fnt1)
img1.text((570, 1000), str(l1[3]), fill=fill2, font=fnt1)
# img.show()
# img.save(path2) # Save the image in new location or path
#####
import tkinter as tk
from tkinter import filedialog
import win32print
import win32api
my_w = tk.Tk() # Parent winow
my_w.geometry("400x300") # Size of the window, width x heiht
my_w.title("www.plus2net.com") # title of the window
font1 = ("times", 26, "bold") # font size style
l1 = tk.Label(
my_w, text="Save File or Print File", width=20, font=font1, anchor="center"
)
l1.grid(row=1, column=1, columnspan=2, pady=50)
b1 = tk.Button(my_w, text="Save", bg="yellow", width=10, command=lambda: save_file())
b1.grid(row=2, column=1)
b2 = tk.Button(
my_w, text="Print", bg="lightgreen", width=10, command=lambda: print_file()
)
b2.grid(row=2, column=2)
def save_file():
file = filedialog.asksaveasfilename(
filetypes=[("PDF file", ".pdf"), ("JPEG file", ".jpeg"), ("PNG file", ".png")],
defaultextension=".jpeg",
)
path2 = file
img.save(path2)
def print_file():
choices = [printer[2] for printer in win32print.EnumPrinters(2)]
print(*choices)
for row in choices:
print(row)
win32print.SetDefaultPrinter(choices[2])
# path2 = "F:\\testing\\images\\certificate_12.pdf" # Path of PDF file
win32api.ShellExecute(0, "print", path2, None, ".", 0)
my_w.mainloop()
#####
Use your own or Download a sample blank certificate here.Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.