- Create a new image
- Open, Show & Save images (PIL)
- Paste, Merge, Blend images (PIL)
- How to Draw shapes images (PIL)
- How to Crop an image (PIL)
- How to Add Text to images (PIL)
- How to Add Frames to images (PIL)
- How to Resize an image (PIL)
- Brightness, Contrast, Saturation
- Convert image to Grayscale | B&W
- Create Photo Collages
- Digital Image Color Modes
- Digital Image Basics
- Image Manipulation w/ PIL
- Batch Resize Multiple Images (PIL)
- Watermarking Images
- Difference Between 2 Images (PIL)
How to crop images with Python (PIL): The Ultimate Guide
Cropping is probably one of the most commonly used image editing tasks in both mobile apps and image editing software for desktops.
In this tutorial we will demonstrate how to crop images using Python’s PIL library. Image cropping is sometimes used synonymously with image clipping or image trimming as well as image cutting.
Let’s dive in and start checking out a few examples…
Contents
- Introduction
- What is image cropping?
- What to do with cropping?
- Simple cropping with .crop() method
- How to trim the sides of an image?
- Case 1: Removing frames from an image
- Case 2: Removing text from an image
- Batch cropping images with Python
- Cropping images in geometric shapes
- How to crop images in Text Shapes
- How to batch crop images with Python
- Summary
What is image cropping?
Cropping is a verb with a very old agricultural root word cropp. Cropp meant the top of a herb in Old English (kropf in Old High German) and the meaning of cropping as a verb evolved as humankind became more civilized and industrialized to mean “to cut off the tip of something” (such as cropping fabric in fashion, cropping produce in agriculture or cropping hair in personal care etc.).
Similarly, cropping means to cut off, trim or extract a piece of image in image editing context. With the surge of digital photography and mobile phones this term became extremely popular and its the main feature in almost every photo editing software or app.
We will cover the basic computational image cropping methods in this Python tutorial as well as other more advanced programmatic cropping techniques that can trim images in various geometric shapes and even based on text.
What can I do with cropping?
Image cropping is a major image editing operation and it can be useful for a variety of purposes.
- Cropping in general (usually rectangular) can be useful to:
- leave out certain parts of the image
- reduce the size of an image
- trim the sides/frames of images
- Cropping in circular or other geometric shapes can be useful to:
- create profile pictures
- generate new image items to paste on another image
- generate creative promotional material
- supplement/decorate pitch decks, white papers, reports etc.
- Additionally, cropping images in text shapes allows:
- generating creative banners,
- slogans,
- titles
- inspirational quotes,
- social media posts,
- consulting proposals
- and similar material with very aesthetic decorative elements.
We will demonstrate all of these cropping methods with Python below and build from the most simplistic to more complex cropping implementations.
Holy Python is reader-supported. When you buy through links on our site, we may earn an affiliate commission.
Image.crop method
Crop method is quite simple using Python’s PIL library. Let’s first import the modules we are going to use.
We will only need the Image
module but we might need ImageDraw
and ImageFont
later for more advanced image cropping implementations.
from PIL import Image, ImageDraw, ImageFont
.crop
method of PIL’s Image module is the most straightforward way to crop images.img_xyz.crop((x0,y0,x1,y1))
img = Image.open('pup_running_original.jpg')
img.show()
And then we can crop this image as below and we can assign the returned image which will be cropped to a variable named cropped.img.
cropped_img=img.crop((50,280,450,650))
cropped_img.show()
.show()
method after our Python codes.Original Image
I think it’s a Bichon Frise but I’m not sure.
Photo cred: Caleb Fisher @Unsplash.
Cropped Image
After adding the Python code below to our initial code we get the image above.
cropped_img=img.crop((50,280, 450,650))
cropped_img.show()
Trimming the Sides
Case 1: Removing Frames from an Image
img = Image.open('/home/holypython/quote_with_frame.png')
x,y = img.size
img=img.crop((200,200,x-200,y-200))
img.show()
Case 2: Removing Text from an Image
Our second example is based on an image with some text at the bottom. Let’s say this textual information became obsolete and needs to be removed from the image. Luckily it’s at the bottom edge of the image and cropping a bit from the bottom won’t hurt anything. We can easily implement the following Python code to achieve our image editing objective.
Like the previous example this Python code can be applied in a for loop or a while loop to scale the same implementation and achieve batch cropping results.
Below, we have a lovely photo of a yellow van on a desert road. Oftentimes old digital cameras had automatic settings to add date as textual information printed right on the image. A bit of a disruptive practice from the early days of digital photography.
Check out the image below. We will conveniently crop this text using Python’s PIL library.
Our code uses the .crop method which again requires box coordinates (x0, y0, x1, y1)
. This time, we are starting from the very top left of the image (x0=0 & y0=0) and the box goes all the way to the right (x1=full width) while the box leaves a small margin from the bottom (y1=full height minus 60 pixels). Et voila!
img = Image.open('/home/holypython/van_desert_road.png')
x,y = img.size
img=img.crop((0,0,x,y-60))
img.show()
If you had 10.000 images to edit, the 4 line Python code above could be a lifesaver. Similar situation can arise from space imagery (due to hardware or organization implementations) as well as medical imaging in the healthcare industry.
Below, you can see our Python tutorial’s section regarding batch cropping applications.
Batch Cropping Images with Python
import os
for i in os.listdir():
print(i)
Output:
samuele-errico-piccarini-JEBqFu2AOOA-unsplash.jpg
john-fowler-aaIN3y2zcMQ-unsplash.jpg
sergey-pesterev-JV78PVf3gGI-unsplash.jpg
pietro-de-grandi-T7K4aEPoGGk-unsplash.jpg
pine-watt-2Hzmz15wGik-unsplash.jpg
ricardo-gomez-angel-dTSaC-S-7fs-unsplash.jpg
…
Once we can effortlessly get all the file names we can easily use “Python for loops or while loops” to iterate our image cropping Python scripts on them.
import os
for i in os.listdir():
img = Image.open(i)
x,y = img.size
new_img = img.crop(0,100,x,y)
new_img.save(i[:-3]+"_cropped.png")
Cropping Images in Geometric Shapes with Python
If you have been trying to crop images in circular or other geometrical shapes to no avail, you are in luck. We will demonstrate how to do exactly that in this session.
We will also stick to the PIL (pillow) image editing library 100%. Although similar results can be achieved using the opencv library, it is not as intuitive or user-friendly for this purpose. Even just opening and closing a window to show the images can be a hassle in opencv.
from PIL import Image, ImageDraw, ImageFilter, ImageFont
img = Image.open('rishi-ragunathan-fs6NPHYMN7o-unsplash.jpg').convert("RGBA")
background = Image.new("RGBA", img.size, (0,0,0,0))
mask = Image.new("RGBA", img.size, 0)
draw = ImageDraw.Draw(mask)
#draw.regular_polygon((300,300,300), 3, rotation=360, fill='green', outline=None)
draw.ellipse((300,50,650,400), fill='green', outline=None)
mask.show()
new_img = Image.composite(img, background, mask)
new_img.show()
Let’s talk about the technique we are going to apply to achieve geometric cropping for a sec. We will use Image module’s .composite method for our purpose.
Image.composite method is used for merging images or pasting an image on top of another.
We also know that RGBA images have an alpha channel in addition to RGB (red-green-blue) color channels and alpha channel can be used to manage the transparency levels of the image. You can read about image modes with Python for more fundamental computational photography knowledge.
So then, we can create a fully transparent new image (alpha turned down to 0, RGB doesn’t matter so anything between 0-255.) and then paste our image on top of this transparent canvas. While pasting the new image, we can also use the mask argument which will ensure pasting is done based on the shape of that mask.
Here is how it looks in theory:
new_img = Image.composite(img, background, mask)
background, new_image and mask are all image objects which we are using for different purposes.
- img: Actual image that’s being cropped
- background: 100% transparent background layer
- mask: The shape in which image will be cropped, used as mask layer
Circular Cropping
For circular cropping we need to create a mask in circle shape. We can do this by drawing a circle on a transparent layer and fill it with any color.
Circle is a special type of ellipse where all points are in equal distance from the center and we can draw a circle using the .ellipse method from the ImageDraw module. The only trick is the box needed to draw the circle needs to be a square. This can be achieved by following.
x1-x0 = y1-y0
when applying the ellipse drawing in this method: ImageDraw.ellipse((x0, y0, x1, y1))
Below you can find the Python code that crops a portrait in circular shape in 5 steps.
- We will open the image to be cropped (img)
- We will create a transparent background (background)
- We will create a transparent mask layer (mask)
- We will draw a circle on the mask layer (mask)
- We will paste the img on background based on the mask.
from PIL import Image, ImageDraw, ImageFilter, ImageFont
img = Image.open('man_portrait.jpg').convert("RGBA")
background = Image.new("RGBA", img.size, (0,0,0,0))
mask = Image.new("RGBA", img.size, 0)
draw = ImageDraw.Draw(mask)
draw.ellipse((20,190,630,800), fill='green', outline=None)
new_img = Image.composite(img, background, mask)
new_img.show()
Here the box has equal sides horizontally and vertically to create a circular mask.
630-20 = 610
800 – 190 = 610
Original Image
Circular Cropping Output
Elliptical Cropping
from PIL import Image, ImageDraw, ImageFilter, ImageFont
img = Image.open('woman_portrait.jpg').convert("RGBA")
background = Image.new("RGBA", img.size, (0,0,0,0))
mask = Image.new("RGBA", img.size, 0)
draw = ImageDraw.Draw(mask)
draw.ellipse((70,70,470,540), fill='green', outline=None)
new_img = Image.composite(img, background, mask)
new_img.show()
Original Image
Elliptical Cropping Output
You can also use this tutorial about automated face recognition with Python and merge it with Batch Cropping techniques explained in this tutorial to apply circular face cropping to thousands or even millions of images.
Triangular Cropping
ImageDraw.regular_polygon(bounding_circle, n_sides, rotation=0, fill=None, outline=None)
from PIL import Image, ImageDraw, ImageFilter, ImageFont
img = Image.open('/home/usa/Downloads/Wallpaperz/nick-perez-duvq92-VCZ4-unsplash.jpg').convert("RGBA")
background = Image.new("RGBA", img.size, (0,0,0,0))
mask = Image.new("RGBA", img.size, 0)
draw = ImageDraw.Draw(mask)
draw.regular_polygon((300,300,300), 3, rotation=360, fill='green', outline=None)
new_img = Image.composite(img, background, mask)
base_img = Image.new("RGBA", (4000, 4000))
base_img.paste(new_img, (300,300), new_img)
base_img.show()
Here the bounding circle starts at point (300,300) and has a radius of 300 as well. Triangle is fit inside this circle. Then we use this triangle drawing as a mask to past our image in triangular shape using the .composite method.
Using the same methods you can even crop images in arc shapes or pieslices which is a circular shape with a degree meaning you can create semi-circles or any incomplete circle shape based on the degree (360 degrees would yield a full circle).
Here are a couple of more examples for triangular cropping with Python’s PIL image editing library.
Pentagonal Cropping
We can apply polygon drawing to create a pentagonal (5 sided) shape and create a pentagonal cropping with Python based on that drawing similar to the examples above.
The Python code’s drawing section for that will include the following snippet.
draw.regular_polygon((1500,1000,1300), 5, rotation=360, fill='green', outline=None)
- Bounding_circle: This is a tuple with 3 elements (x,y,radius). X,y are the coordination to start the crop from and the radius is the radius of the circle in which pentagon will be drawn. We’re using (1500,1000,1300) for a 1300 pixel radius circling the pentagon and starting points of (1500,1000)
- n_sides: This is the parameter for sides of the polygon. For Pentagon we are entering 5.
Hexagonal Cropping
Hexagon is a polygon shape similar to a pentagon except it has 6 sides instead of 5.
Following the same methods here we are drawing a hexagon and then using it as mask layer to create an impressive hexagonally cropped Python image.
draw.regular_polygon((3600,1800,2300), 6, rotation=360, fill='green', outline=None)
Regular polygon method (ImageDraw.regular_polygon) takes a tuple (bounding_circle) as first argument which consists of x,y coordinates and the radius of the polygon’s outer circle. (x,y,r). 6 is passed to n_sides argument for hexagon which is the second one and the rest is rotation, fill and outline colors.
Rounded Rectangle Cropping
To take advantage of rounded rectangle cropping, all you need to do is draw a rounded rectangle as mask layer instead. Below we are drawing a rectangle with rounded corners at 60 degree radius. You can apply the Python code above with the shape in the Python code below to achieve a result as in the image.
draw.rounded_rectangle((20,190,630,800), 60, fill='green', outline=None)
Cropping Images in Text Shapes
Once you understand the logic of cropping images based on mask layers with Python, you can come up with very creative applications. For example text objects can also be drawn on Python images using the PIL image editing library.
So, we can use the ImageFont and ImageDraw modules to draw text objects and use it as the mask layer to crop images based on these text objects.
Results will be very aesthetic and computationally feasible meaning a lot more convenient than resource-hungry GUI photo editing applications. You can use it to create amazing titles, slogans, inspirational quotes, pitch deck headers, blog headers magazine covers etc. etc with filling as any of your favorite images.
Here are some examples.
from PIL import Image, ImageDraw, ImageFilter, ImageFont
img = Image.open('/home/usa/Downloads/Wallpaperz/nick-perez-duvq92-VCZ4-unsplash.jpg').convert("RGBA")
background = Image.new("RGBA", img.size, (0,0,0,0))
mask = Image.new("RGBA", img.size, 0)
draw = ImageDraw.Draw(mask)
font = ImageFont.truetype('Inconsolata-Bold.ttf', 550)
draw.text((50,1100), "HOLYPYTHON", fill='blue', font=font)
new_img = Image.composite(img, background, mask)
new_img.show()
Here is Holypython text cropped from an artistic drawing.
* Please note that following examples follow the same logic with the cropping Python code above. I’m only including the draw text parts to avoid repetition and cluttering the screen. Just replace the relevant lines from the Python example above to reach the same results.
font = ImageFont.truetype('Inconsolata-Bold.ttf', 750)
draw.text((50,1100), "HOLYPYTHON", fill='blue', font=font)
This one is more like a skincare product slogan or maybe a header from a biomedical startup’s pitch deck. You can almost feel the vitality of the leaves. Considering how easy it is to crop such visuals with Python it’s a hugely successful experiment already.
font = ImageFont.truetype('Inconsolata-Bold.ttf', 750)
draw.text((50,1100), "REVITALIZE", fill='blue', font=font)
This one is written with Inconsolata-Black.ttf font. You can list your system’s fonts using fc-list in Linux. (Or this might be more useful: fc-list | grep .ttf
)
(In this example piped with the results of the fc-list
command, grep
is an ultra useful Linux command. You can check out this tutorial about using grep recursively to search contents of files in your operating system.)
In Windows and Mac you can open Font GUI applications of the operating systems to explore the fonts installed in your system. You can always install new fonts using Google Font free font repository as well.
font = ImageFont.truetype('Inconsolata-Black.ttf', 750)
draw.text((50,1100), "REDEFINE", fill='blue', font=font)
font = ImageFont.truetype('Inconsolata-Black.ttf', 1250)
draw.text((50,1100), "BREEZE", fill='blue', font=font)
Summary
In this Python Tutorial we extensively covered different techniques to crop images using Python and its image editing PIL (pillow) library.
We took advantage of different modules from PIL such as Image, ImageDraw and ImageFont and we used several methods applied on Python PIL image objects. These methods are:
- .composite,
- .crop
- .draw,
- .text,
- .polygon,
- .rounded_rectangle,
- .ellipse,
- .open
- .show
You can, of course, save these generated image objects with the .save method instead of just showing them with the .show method. You can refer to this quick tutorial how to save Python images.
We hope this computational photography tutorial was useful for our audience. Computational photography and digital image editing can be incredibly beneficial for organizations of all sizes and startups and they open many doors to impressive creativity.