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
🎥 Join me live on YouTubePassionate about coding and teaching, I publish practical tutorials on PHP, Python, JavaScript, SQL, and web development. My goal is to make learning simple, engaging, and project‑oriented with real examples and source code.