~jshsj/simple_resizer

08090d939a6c713aeca65abb1904c9bb8c42f26d — JSH 1 year, 10 months ago master
Initial commit
3 files changed, 108 insertions(+), 0 deletions(-)

A .gitignore
A README.md
A script.py
A  => .gitignore +2 -0
@@ 1,2 @@
output
.vscode

A  => README.md +23 -0
@@ 1,23 @@
# Simple Web Images

Simple image resize and optimization tool. Resizes and optimizes images.

### Requirements

Python > 3, Pillow

### Usage

Run it. Uses the current working directory as source. A `output` directory is created for resized images. Resized images are JPEGs.

Tip: `chmod +x script.py`, then register it as an alias and run it from anywhere with a simple command.

**Parameters:**

--size, -s: Takes a value in the form of `[width]x[height]` and resizes the images accordingly. If height is ommited, it scales images. Aspect ratio is always kept. Default: 1280x960

--inputname, -i: If provided, resize specified image. Otherwise it looks for images in the current working directory.

--quality, -q: Image optimization quality. Default: 85

--outname, -o: Name for resized images. If multiple images are created, they are numbered, 0-indexed. Default: "image"

A  => script.py +83 -0
@@ 1,83 @@
#!/usr/bin/python3

from PIL import Image
import sys
import glob
import re
import os
import argparse


class SizeParse(argparse.Action):
    def __init__(self, option_strings, dest, nargs=None, **kwargs):
        if nargs is not None:
            raise ValueError("nargs not allowed")
        super(SizeParse, self).__init__(option_strings, dest, **kwargs)

    def __call__(self, parser, namespace, values, option_string=None):
        try:
            size = tuple(map(int, values.split("x")))
            if len(size) > 2:
                raise ValueError(
                    "No third value allowed. Size must be in the form of [width]x[height]."
                )
            setattr(namespace, self.dest, size)
            print("%r %r %r" % (namespace, size, option_string))
        except:
            raise ValueError("Size must be in the form of [width]x[height]")


def convert_file(filename, size, quality, outname):
    cwd = os.getcwd()
    basename = os.path.basename(filename)
    img = Image.open(f"{cwd}/{basename}")
    img.thumbnail(size, Image.ANTIALIAS)
    filename = f"{cwd}/{outname}.jpg"
    img.save(filename, format="JPEG", quality=quality, optimize=True, progressive=True)


def handle_multiple_files(args):
    cwd = os.getcwd()
    files = [
        file
        for file in os.listdir(cwd)
        if re.search(r".jpeg|.jpg|.png", file, flags=re.IGNORECASE)
    ]
    count = 0
    os.makedirs("output", exist_ok=True)
    for image_file in files:
        output_name = f"output/{args.outname}_{count}"
        convert_file(image_file, args.size, args.quality, output_name)
        count += 1


parser = argparse.ArgumentParser(
    prog="Images for Web", description="Resize and optimize Images"
)
parser.add_argument(
    "--size",
    "-s",
    help="Size of the new image(s). Default is 1280x960. Images are scaled so the aspect ratio is kept.",
    action=SizeParse,
    default=(1280, 960),
)
parser.add_argument(
    "--inputname",
    "-i",
    type=str,
    help="File to be resized. If not provided, it will convert all images in current working directory.",
)
parser.add_argument(
    "--quality", "-q", type=int, help="Quality of the optimized image.", default=85
)
parser.add_argument(
    "--outname", "-o", type=str, help="Output name or naming pattern.", default="image"
)

args = parser.parse_args()

if args.inputname == None:
    handle_multiple_files(args)
else:
    convert_file(args.inputname, args.size, args.quality, args.outname)