Unit 12.1A · Term 1

PIL Drawing Primitives

The ImageDraw module from PIL lets you draw graphic primitives — lines, rectangles, ellipses, polygons, and text — directly onto images using Python code.

Learning Objectives

  • 12.6.2.3 Apply graphic primitives to create drawings

Lesson Presentation

12.1A-pil-drawing.pdf · Slides for classroom use

Conceptual Anchor

The Canvas & Brush Analogy

Image.new() creates the canvas. ImageDraw.Draw(img) gives you a brush. You then call methods like draw.rectangle() or draw.ellipse() to paint shapes on the canvas — just like a graphics editor, but in code.

Rules & Theory

Setting Up a Drawing

from PIL import Image, ImageDraw # Create canvas and draw object img = Image.new("RGB", (400, 300), (255, 255, 255)) # white bg draw = ImageDraw.Draw(img)

Drawing Primitives

Method Parameters Description
draw.line() [(x1,y1), (x2,y2)], fill, width Draw a straight line
draw.rectangle() [(x1,y1), (x2,y2)], fill, outline Draw a rectangle (top-left, bottom-right)
draw.ellipse() [(x1,y1), (x2,y2)], fill, outline Draw an ellipse within bounding box
draw.polygon() [(x1,y1), (x2,y2), ...], fill, outline Draw a polygon with any number of vertices
draw.arc() [(x1,y1), (x2,y2)], start, end, fill Draw an arc (part of ellipse outline)
draw.point() (x, y), fill Draw a single pixel
draw.text() (x, y), "text", fill, font Draw text on the image

Parameter Reference

Parameter Meaning
fill Interior color as RGB tuple, e.g. (255, 0, 0)
outline Border color as RGB tuple
width Line/border thickness in pixels
(x1, y1) Top-left corner of bounding box
(x2, y2) Bottom-right corner of bounding box

Worked Examples

1 Drawing Basic Shapes

from PIL import Image, ImageDraw img = Image.new("RGB", (400, 300), (255, 255, 255)) draw = ImageDraw.Draw(img) # Red rectangle draw.rectangle([(50, 50), (150, 120)], fill=(255, 0, 0), outline=(0, 0, 0)) # Blue circle (ellipse in square bounding box) draw.ellipse([(200, 50), (300, 150)], fill=(0, 0, 255), outline=(0, 0, 0)) # Green line draw.line([(50, 200), (350, 200)], fill=(0, 128, 0), width=3) img.save("shapes.png")

2 Drawing a Simple House

from PIL import Image, ImageDraw img = Image.new("RGB", (400, 400), (135, 206, 235)) # sky blue bg draw = ImageDraw.Draw(img) # Ground draw.rectangle([(0, 300), (400, 400)], fill=(34, 139, 34)) # House body draw.rectangle([(100, 180), (300, 300)], fill=(210, 180, 140), outline=(0, 0, 0)) # Roof (triangle) draw.polygon([(90, 180), (200, 100), (310, 180)], fill=(139, 69, 19), outline=(0, 0, 0)) # Door draw.rectangle([(175, 230), (225, 300)], fill=(101, 67, 33), outline=(0, 0, 0)) # Window draw.rectangle([(120, 210), (160, 250)], fill=(173, 216, 230), outline=(0, 0, 0)) # Sun draw.ellipse([(320, 30), (380, 90)], fill=(255, 255, 0)) img.save("house.png")

3 Adding Text

from PIL import Image, ImageDraw, ImageFont img = Image.new("RGB", (400, 200), (0, 0, 0)) draw = ImageDraw.Draw(img) # Default font (basic) draw.text((20, 80), "Hello, PIL!", fill=(255, 255, 255)) # Custom font (if available) try: font = ImageFont.truetype("arial.ttf", 36) draw.text((20, 30), "Big Text", fill=(255, 200, 0), font=font) except: pass img.save("text_demo.png")

Common Pitfalls

Bounding Box — Not Center + Radius

Circles/ellipses use a bounding box [(x1,y1), (x2,y2)], NOT center + radius. For a circle at center (200, 150) with radius 50, use: [(150, 100), (250, 200)].

Tasks

Apply

Draw a traffic light: black rectangle with three circles (red, yellow, green) inside.

Apply

Draw a smiley face using ellipses and arcs. Save it as "smiley.png".

Create

Create a landscape scene (sky, ground, sun, trees) using at least 5 different drawing primitives.

Self-Check Quiz

Q1: How do you create a draw object?

draw = ImageDraw.Draw(img) — pass the image you want to draw on.

Q2: How do you draw a circle with PIL?

Use draw.ellipse() with a square bounding box, e.g. draw.ellipse([(50,50),(150,150)], fill="red").

Q3: What's the difference between fill and outline?

fill is the interior color of the shape. outline is the border color.