5

I've been working on images for a website and find out that .webp format is much more compact than .jpeg or .png find more on Docs.

Now I have a folder with almost 25 images & I want to convert all into .webp format. Can anyone suggest me how to convert all by using just a python script without using online tools.

2 Answers2

4

Well first of all you have to download the cwebp compressor tool according to your machine(Windows|Linux) from here.

Now after extracting the folder in C:\Program Files\ you have to set path to cwebp.exe, below is my path Path:: C:\Program Files\libwebp\bin

Open cmd to check if you have done right till now.

  • cmd> cwebp -version

cwebp- version

  • cmd> python --version

python --version

Now it's super easy just run the below script and you have your desired output or you can download my repo on github from here

# --cwebp_compressor.py--

# cmd> python cwebp_compressor.py folder-name 80

import sys
from subprocess import call
from glob import glob

#folder-name
path = sys.argv[1]
#quality of produced .webp images [0-100]
quality = sys.argv[2]

if int(quality) < 0 or int(quality) > 100:
    print("image quality out of range[0-100] ;/:/")
    sys.exit(0)

img_list = []
for img_name in glob(path+'/*'):
    # one can use more image types(bmp,tiff,gif)
    if img_name.endswith(".jpg") or img_name.endswith(".png") or img_name.endswith(".jpeg"):
        # extract images name(image_name.[jpg|png]) from the full path
        img_list.append(img_name.split('\\')[-1])


# print(img_list)   # for debug
for img_name in img_list:
    # though the chances are very less but be very careful when modifying the below code
    cmd='cwebp \"'+path+'/'+img_name+'\" -q '+quality+' -o \"'+path+'/'+(img_name.split('.')[0])+'.webp\"'
    # running the above command
    call(cmd, shell=False)  
    # print(cmd)    # for debug
  • Why not run it with both -near_lossless 80 and the lossy, and then take the smaller? – Jyrki Alakuijala Apr 03 '19 at 19:48
  • @JyrkiAlakuijala well when I started with webp conversion I found it tidious to convert all 25 images one-by-one one.....the above code is more on conversion for batch images....well you can do this in your code...nice idea – Pankaj Kumar Gautam Apr 03 '19 at 20:01
  • I had to change `call(cmd, shell=False)` to `call(cmd, shell=True)` because we are passing a shell command. [reference](https://stackoverflow.com/a/18962815/3578289). – eMad Mar 18 '21 at 22:06
  • Thanks! I modified it to my needs (use with shell, save files in separate folder). Works well! My version: https://gist.github.com/apiwonska/d2a0938fc68909e14f83876e72a55325 – ann.piv Dec 15 '21 at 19:20
0

Old post but I wanted to share my updated version that asks to select a folder, works recursively in this folder and subfolders, asks your for the desired quality and tells you how many images have been converted.

First steps stays the same you need cwebp and python

# --cwebp_compressor.py--

import sys
from subprocess import call
from glob import glob
import tkinter as tk
from tkinter import filedialog
import os
from tqdm import tqdm

# open a prompt to select the folder
root = tk.Tk()
root.withdraw()
path = filedialog.askdirectory()

# open a prompt to enter the desired quality
quality = input("Enter the desired quality (0-100): ")

if int(quality) < 0 or int(quality) > 100:
    print("Image quality out of range [0-100] ;/:/")
    sys.exit(0)

img_list = []
jpg_count = 0
png_count = 0
jpeg_count = 0
bmp_count = 0
tiff_count = 0
for dirpath, _, filenames in os.walk(path):
    for img_name in filenames:
        # one can use more image types(bmp,tiff,gif)
        if img_name.endswith(".jpg"):
            jpg_count += 1
        elif img_name.endswith(".png"):
            png_count += 1
        elif img_name.endswith(".jpeg"):
            jpeg_count += 1
        elif img_name.endswith(".bmp"):
            bmp_count += 1
        elif img_name.endswith(".tiff") or img_name.endswith(".tif"):
            tiff_count += 1
        else:
            continue
        # extract images name(image_name.[jpg|png]) from the full path
        img_list.append(os.path.join(dirpath, img_name))

with tqdm(total=len(img_list), desc="Compressing Images") as pbar:
    for img_name in img_list:
        # though the chances are very less but be very careful when modifying the below code
        cmd='cwebp \"'+img_name+'\" -q '+quality+' -o \"'+os.path.splitext(img_name)[0]+'.webp\"'
        # running the above command
        call(cmd, shell=False)
        pbar.update(1)

print("Compression completed!\n")
print(f"The compressor converted and compressed {jpg_count} .jpg, {png_count} .png, {jpeg_count} .jpeg, {bmp_count} .bmp, and {tiff_count} .tiff files.")

input("Press Enter to exit...")

DevSolal
  • 1
  • 1