xbp 0.9.1

XBP is a zero-config build pack that can also interact with proxies, kafka, sockets, synthetic monitors.
Documentation
# -*- coding: utf-8 -*-
import sys
import os
from PIL import Image
from collections import Counter

def get_most_dominant_color(img):
    img = img.convert("RGBA")
    pixels = list(img.getdata())
    opaque_pixels = [p[:3] for p in pixels if p[3] > 0]
    if not opaque_pixels:
        return (0, 0, 0)
    return Counter(opaque_pixels).most_common(1)[0][0]

def fill_transparent_bars(img, fill_color):
    width, height = img.size
    pixels = img.load()
    for y in range(height):
        # Fill left transparent bar
        x = 0
        while x < width and pixels[x, y][3] == 0:
            pixels[x, y] = fill_color + (255,)
            x += 1
        # Fill right transparent bar
        x = width - 1
        while x >= 0 and pixels[x, y][3] == 0:
            pixels[x, y] = fill_color + (255,)
            x -= 1
    return img

def resize_and_crop_center(input_path, output_path, target_width, target_height):
    img = Image.open(input_path).convert("RGBA")
    orig_width, orig_height = img.size

    # Fix: Prevent division by zero and invalid target sizes
    if orig_height == 0 or target_height <= 0 or target_width <= 0:
        raise ValueError("Invalid image or target size.")

    # Scale to fit the target box, covering the whole area (may crop)
    scale_w = target_width / orig_width
    scale_h = target_height / orig_height
    scale = max(scale_w, scale_h)
    new_width = max(1, int(round(orig_width * scale)))
    new_height = max(1, int(round(orig_height * scale)))
    img_resized = img.resize((new_width, new_height), Image.LANCZOS)

    # Crop to the center
    left = max(0, (new_width - target_width) // 2)
    upper = max(0, (new_height - target_height) // 2)
    right = left + target_width
    lower = upper + target_height
    img_cropped = img_resized.crop((left, upper, right, lower))

    dominant_color = get_most_dominant_color(img_cropped)
    img_filled = fill_transparent_bars(img_cropped, dominant_color)
    img_filled.save(output_path)

def main():
    import argparse

    parser = argparse.ArgumentParser(
        description="Resize an image to a specific width and height, cropping as needed to fill the box. Fill any transparent bars on either side with the most dominant color."
    )
    parser.add_argument("input", help="Input image file")
    parser.add_argument("--width", type=int, default=160, help="Target width (default: 160)")
    parser.add_argument("--height", type=int, default=220, help="Target height (default: 220)")
    args = parser.parse_args()

    input_path = args.input
    base, ext = os.path.splitext(input_path)
    output_path = f"{base}.resized{ext}"

    try:
        resize_and_crop_center(input_path, output_path, args.width, args.height)
        print(f"Resized and cropped image saved to {output_path}")
        #  open the image
        img = Image.open(output_path)
        img.show()
    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)

if __name__ == "__main__":
    main()