Scaling and Cropping images using Python
Since I used a lot of pictures (and also very large ones in the beginning), this had a huge impact on the speed of the page. Since PageSpeed ββis a not unimportant ranking factor for search engines like Google and Co, you should of course make a page as fast as possible.
The images used here are mainly satellite images from ESA, which are licensed under the CC BY-SA 3.0 IGO IGO) and may therefore also be used for your own purposes under certain conditions.
These pictures are often ~ 30MB, which is a bit too big for a website. Since I didn't want to crop all pictures manually, I decided to solve this problem with Python or Pillow.
Pillow library
Pillow is a Python library for image processing that can be installed on with (assuming you have Python already installed)
pip install Pillow
Finally you can import the library with
from PIL import Image
into your Python script.
All images for posts are in a separate "images /" folder in the root directory of the project.
First, all ".jpg" files in a certain directory are opened with Pillow and all file names are saved in an array. In addition, a variable is required and can later access any name in the array.
count = 0 image_list = [] for file in glob.iglob('path/to/images/*.jpg'): im=Image.open(file) image_list.append(os.path.basename(file))
Define sizes and calculate aspect ratio
Now you should know to which sizes the pictures should be cut and whether, for example, the proportions should be retained. For all "PostCover" (pictures in posts) the aspect ratio is ignored and the picture is simply cut to a certain size, which is declared in a global variable.
size = (1903,453) #(width,height)
With all "PostThumbnails" (picture preview) the aspect ratio should be retained and only scaled smaller. A global standard width is defined for this.
basewidth = 500
Then the original width and height of the images are determined, as we need them to be able to calculate and maintain the aspect ratio. Only the new height is needed here, as the standard width has already been predefined.
width, height = im.size wpercent = (basewidth / float(im.size[0])) hsize = int((float(im.size[1]) * float(wpercent)))
Cropping and Rescaling
Now you can cut the images with Image.crop
or scale them with Image.resize
. The new width "basewidth" and the calculated height "hsize" are now used as parameters for scaling.
imThumbnail = im.resize((basewidth, hsize), Image.LANCZOS) imCover = im.crop(((width-size[0])//2, (height-size[1])//2, (width+size[0])//2, (height+size[1])//2))
Then I renamed the thumbnail and saved both new files under static/assets
with a quality of "85" .
With the additional parameter "optimize = True" a few KB can be saved.
newCover = 'static/assets/{}'.format(image_list[count]) newThumbnail = 'static/assets/{}_thumbnail.jpg'.format(image_list[count].replace(".jpg", "")) imCover.save(newCover,optimize=True,quality=85) imThumbnail.save(newThumbnail,optimize=True,quality=90) count +=1
Complete script:
from PIL import Image import glob, os count = 0 image_list = [] basewidth = 500 size = (1903,453) for file in glob.iglob('path/to/images/*.jpg'): im=Image.open(file) image_list.append(os.path.basename(file)) width, height = im.size wpercent = (basewidth / float(im.size[0])) hsize = int((float(im.size[1]) * float(wpercent))) imThumbnail = im.resize((basewidth, hsize), Image.LANCZOS) imCover = im.crop(((width-size[0])//2, (height-size[1])//2, (width+size[0])//2, (height+size[1])//2)) newCover = 'static/assets/{}'.format(image_list[count]) newThumbnail = 'static/assets/{}_thumbnail.jpg'.format(image_list[count].replace(".jpg", "")) imCover.save(newCover,optimize=True,quality=85) imThumbnail.save(newThumbnail,optimize=True,quality=90) count +=1
Run script automatically
In order not to have to run the script manually every time, you can add the following to "package.json".
"img-optimize": "py ./src/utils/resize_images.py"
So you can optimize all images automatically with npm run img-optimize
.
First published August 31, 2020
Have you published a response to this? Send me a webmention by letting me know the URL.
Found no Webmentions yet. Be the first!
About The Author
Geospatial Developer
Hi, I'm Max (he/him). I am a geospatial developer, author and cyclist from Rosenheim, Germany. Support me