These ImageOps functions provide methods to resize images.
The expand
function adds a solid colour border around the image, like this:
In this case we have added a yellow border that is 40 pixels wide. This means that the width and height of the new image are both increased by 80 pixels.
expand
accepts a single parameter for the border width, so the four borders will always have equal widths.
The image inside the borders is pixel-for-pixel identical to the original.
Here is the code:
from PIL import Image, ImageOps im = Image.open('carousel-small.jpg') im = ImageOps.expand(im, 40, 'yellow') im.save('imageops-expand-40.jpg')
expand
has the following signature:
ImageOps.expand(image, border=0, fill=0) # returns a new image
image
is the original image.border
gives the width of the border in pixels, and the same width is used on all 4 sides of the image.fill
gives the colour of the border (defaults to black if not supplied)crop
removes a band of pixels from the each of the 4 sides of the image, leaving just the central part, like this:
In this case we have removed a 20 pixel band from each edge. This means that the width and height of the new image are both decreased by 40 pixels.
This diagram shows the original image, and the red rectangle indicates the boundary that is cropped:
crop
accepts a single parameter for the crop width, so the top, bottom, left and right will all be cropped by the same amount.
The remaining image corresponds to the central part of the original image.
Here is the code:
im = Image.open('carousel-small.jpg') im = ImageOps.crop(im, 20) im.save('imageops-crop-20.jpg')
crop
has the following signature:
ImageOps.crop(image, border=0) # returns a new image
image
is the original image.border
gives the width of area to be removed, in pixels. The same width is used on all 4 sides of the image.scale
increases or decreases the size of the image by a scale factor. Here is an example of scaling the image by a factor of 2. The new image has twice the width and twice the height, and the image content is scaled to match:
Here is the code:
im = Image.open('carousel-small.jpg') im = ImageOps.scale(im, 2) im.save('imageops-scale-2.jpg')
Here is another example, again using the original image, with scale factor of 0.5. This creates an image with that is half the width and height:
The code is the same as the previous example, but with a scale factor of 0.5 passed in to the scale
function.
scale
has the following signature:
ImageOps.scale(image, factor, resample=3) # returns a new image
image
is the original image.factor
is the scaling factor to be applied.resample
specifies the resampling method to be applied, see below.Whenever we scale, rotate or apply other transformations to a pixel image, problems such as jagged edges and other unwanted effect can occur. We can apply a filter to reduce these effects. By default, Pillow uses a bicubic filter, which usually does a pretty good job. The resample
parameter allows us to choose one of several other filters instead. See the section on filters for more information.
The 'pad' function allows you to change the shape of an image, without stretching or distorting the image. It does this by scaling the image so it fits the required size, and then adding padding to the image as necessary.
Specifically, pad
scales the image to be as big as it can be while still fitting in the target size. Depending on the image size and the target size it will either:
It will never do both, because the image will always be scaled so that it either fills the width or fills the height.
Here is the first example. Our original image is 300 by 200 pixels, and we want to pad it to make it 500 by 250 pixels:
Here is how this works:
In this second example, the same original image is padded to a size of 250 by 400 pixels:
This time:
As you can see, mode of operation depends on the aspect ration (ie width/height) of the original image size compared to the target size:
Notice pad
never applies padding to both the width and height.
Here is the code to pad the image to 500 by 250:
im = Image.open('carousel-small.jpg') im = ImageOps.pad(im, (500, 250), color='grey') im.save('imageops-pad-500-250.jpg')
pad
has the following signature:
ImageOps.pad(image, size, method=3, color=None, centering=(0.5, 0.5)) # returns a new image
image
is the original image.size
is the target size, a tuple (or other sequence) of two integers (width, height).method
specifies the resampling method to be applied, see the scale
function or filters article. Default is bicubic.color
is the colour to use as the background when the image is padded, default is black.centering
controls the position of the image, a tuple (or other sequence) of two numbers (x, y). Defaults to (0.5, 0.5), described below.The centering
parameter controls where the image is placed within the target rectangle. It consists of a tuple of two values, (x, y)
.
The x
value determines how the image will be placed horizontally in cases where horizontal padding is used. For example the default value of 0.5 means that 50% of the required padding is placed on the left of the image, and 50% is placed to the right of the image. The padding ie equal on both sides so the image will be centred horizontally.
Similarly, the y
value determines how the image will be placed vertically in cases where vertical padding is used. The default value of 0.5 means that 50% of the required padding is placed above the image, and 50% is placed below the image. The image will be centred vertically.
We will now look at an example where the centering
is set to (0.8, 0.3)
. For cases where horizontal padding is used, the value of 0.8 means that 80% of the padding is on the left, 20% on the right, like this:
For cases where vertical padding is used, the value of 0.3 means that 30% of the padding is at the top, 30% at the bottom, like this:
You can place the image at the top left using (0, 0)
, or at the bottom right using (1, 1)
, and so on.
The 'fit' function allows you to change the shape of an image, without stretching or distorting the image. It does this by scaling the image so it compoletely fills the required size, and then cropping the image as necessary.
Specifically, fit
scales the image to be the smallest size that completely fills the target size. Depending on the image size and the target size it will either:
It will never do both, because the image will always be scaled so that it either fits the width or fits the height.
This function is similar to pad
in that it changes an image into a new size. But whereas pad
shows the entire image and pads any gaps, fit
just fills the space with as much of the image as possible, cropping rather than padding padding.
Here is an example. Our original image is 300 by 200 pixels, and we want to fit it to make it 500 by 250 pixels. This is similar to the first pad
example above:
Here is how this works:
In this second example, the same original image is fitted to a size of 250 by 400 pixels:
This time:
Similar to pad
, the result depends on the aspect ration (ie width/height) of the original image size compared to the target size:
Notice fit
never applies cropping to both the width and height.
Here is the code to fit the image to 500 by 250:
im = Image.open('carousel-small.jpg') im = ImageOps.fit(im, (500, 250)) im.save('imageops-fit-500-250.jpg')
fit
has the following signature:
ImageOps.fit(image, size, method=3, centering=(0.5, 0.5)) # returns a new image
image
is the original image.size
is the target size, a tuple (or other sequence) of two integers (width, height).method
specifies the resampling method to be applied, see the scale
function or filters article. Default is bicubic.centering
controls the position of the image, a tuple (or other sequence) of two numbers (x, y). Defaults to (0.5, 0.5).centering
works in the same way as for pad
, but it is a little less obvious because there is no padding visible. As an illustration, we will take the previous case of fitting to (500, 250)
but with centering
of (0, 0)
:
The image is cropped such that the top left of the original image appears in the top left of the output image.
Here is the same example with centering
of (1, 1)
:
This time the image is cropped such that the bottom right of the original image appears in the bottom right of the output image.
If you found this article useful, you might be interested in the book Computer Graphics in Python, or other books, by the same author.
<<PrevCopyright (c) Axlesoft Ltd 2020