Resize, Convert SVG & Generate Favicons Offline — WordsByEkta🌿

Python Image Tools Automation

Stop Uploading Your Images to Random Websites. Resize, Convert, Compress & Even Generate SVG or ICO Files Yourself.

WordsByEkta🌿  ·  May 2026  ·  Creator Utility

You need to resize an image. Maybe it's a blog banner, a thumbnail, a logo, a product photo. So you open a browser tab, find a site, upload the image, wait, download the result, and hope it didn't destroy the quality or bury you in ads.

Then next week you do it again.

I built a small Python script that does all of this locally — resize to any dimension, convert between PNG and JPG, compress under a file size limit — without uploading a single file anywhere.

Every time you upload an image to a free online tool, you are handing your file to a server you know nothing about. For personal photos, client work, or anything branded — that's a risk you're taking silently.
A sleek flat editorial illustration of an image file icon at the centre of a desk surrounded by PNG, JPG, ICO and SVG format badges connected by dotted arrows, with a Python logo glowing beneath, representing a local image resizing and conversion script — WordsByEkta
Resize, convert, compress. No uploads. No ads. No limits.

What this script does

  • Resize any image to any width and height you choose
  • Convert PNG to JPG or JPG to PNG automatically
  • Accept PNG, JPG, JPEG, WEBP and most common formats
  • Auto-compress only if the file exceeds your size limit
  • Keep the highest possible quality throughout
  • Works for any use case — blogs, social media, apps, client work, personal projects
  • Generate favicon.ico files for apps and websites
  • Convert SVG to PNG, JPG or ICO locally
  • Basic PNG/JPG to SVG tracing for simple logos and icons
  • Save converted files automatically beside the original image

One-time setup

You need Python installed — free from python.org. Then run this once in your terminal or command prompt:

terminal
pip install pillow opencv-python numpy cairosvg

That's it. Never again.

Important for SVG & ICO support on Windows

SVG conversion on Windows needs the GTK/Cairo runtime installed once. Without it, normal PNG/JPG resizing still works — but SVG to PNG/JPG/ICO conversion will fail.

Install the 64-bit GTK Runtime and keep the PATH option checked during installation.

Official download: GTK Runtime Win64 Releases

After installation, restart your terminal or command prompt once.

If SVG conversion fails even after installation, completely close and reopen your terminal once.

The script — copy, save, run

Paste this into a file called image_resizer.py and keep it anywhere on your machine.

image_resizer.py
from PIL import Image import os import cv2 import cairosvg import numpy as np import re input_file = input( "Enter input image file name/path: " ).strip().strip('"') width_input = input( "Enter output width (blank = original): " ).strip() height_input = input( "Enter output height (blank = original): " ).strip() width = int(width_input) if width_input else None height = int(height_input) if height_input else None output_format = input( "Output format? png, jpg, ico or svg: " ).strip().lower() if output_format in ["jpg", "jpeg"]: save_format = "JPEG" elif output_format == "ico": save_format = "ICO" elif output_format == "svg": save_format = "SVG" else: save_format = "PNG" limit_input = input("Size limit? Examples: 100kb, 0.1mb, blank = no limit: ").strip().lower() size_limit_bytes = None if limit_input: if limit_input.endswith("kb"): size_limit_bytes = float(limit_input.replace("kb", "").strip()) * 1024 elif limit_input.endswith("mb"): size_limit_bytes = float(limit_input.replace("mb", "").strip()) * 1024 * 1024 else: # default to KB if only number is entered size_limit_bytes = float(limit_input) * 1024 input_folder = os.path.dirname( os.path.abspath(input_file) ) base_name = os.path.splitext( os.path.basename(input_file) )[0] if input_file.lower().endswith(".svg"): temp_png = "__temp_png__.png" cairosvg.svg2png( url=input_file, write_to=temp_png, ) img = Image.open(temp_png) else: img = Image.open(input_file) if width is None: width = img.width if height is None: height = img.height if output_format in ["jpg", "jpeg"]: output_file = f"{base_name}_{width}x{height}.jpg" save_format = "JPEG" elif output_format == "ico": output_file = f"{base_name}_{width}x{height}.ico" save_format = "ICO" elif output_format == "svg": output_file = f"{base_name}_{width}x{height}.svg" save_format = "SVG" else: output_file = f"{base_name}_{width}x{height}.png" save_format = "PNG" output_file = os.path.join( input_folder, output_file ) if save_format == "SVG": if input_file.lower().endswith(".svg"): with open(input_file, "r", encoding="utf-8") as f: svg_content = f.read() if 'width="' in svg_content: svg_content = re.sub( r'width="[^"]*"', f'width="{width}"', svg_content ) else: svg_content = svg_content.replace( " 300: print("This image is too complex for clean SVG conversion.") print("Use PNG/JPG instead, or trace manually in Inkscape.") exit() paths = [] for contour in contours: if cv2.contourArea(contour) < 5: continue points = contour.squeeze() if len(points.shape) != 2: continue d = f"M {points[0][0]} {points[0][1]} " for point in points[1:]: d += f"L {point[0]} {point[1]} " d += "Z" paths.append(f'') if not paths: print("No clear shapes found. Cannot convert properly to SVG.") exit() svg_content = f''' {chr(10).join(paths)} ''' with open(output_file, "w", encoding="utf-8") as f: f.write(svg_content) print("Basic SVG created.") print("Suitable only for simple logos/icons, not photos.") print("Output file:", output_file) exit() # Convert transparent images safely for JPG if save_format == "JPEG": if img.mode in ("RGBA", "LA", "P"): background = Image.new("RGB", img.size, (255, 255, 255)) background.paste(img, mask=img.split()[-1]) img = background else: img = img.convert("RGB") else: img = img.convert("RGBA") img = img.resize((width, height), Image.LANCZOS) # First save normally if save_format == "JPEG": quality = 95 min_quality = 10 img.save(output_file, "JPEG", quality=quality, optimize=True, progressive=True) if size_limit_bytes: limit_bytes = size_limit_bytes while os.path.getsize(output_file) > limit_bytes: if quality > min_quality: quality -= 5 img.save(output_file, "JPEG", quality=quality, optimize=True, progressive=True) else: # If quality is already very low, reduce dimensions by 10% width = max(1, int(img.width * 0.9)) height = max(1, int(img.height * 0.9)) img = img.resize((width, height), Image.LANCZOS) quality = 85 img.save(output_file, "JPEG", quality=quality, optimize=True, progressive=True) elif save_format == "PNG": img.save(output_file, "PNG", optimize=True) # PNG has limited compression without quality loss. # If still above limit, script tells you to use JPG. if size_limit_bytes: limit_bytes = size_limit_bytes if os.path.getsize(output_file) > limit_bytes: print("PNG is still above your size limit. Use JPG for stronger compression.") elif save_format == "ICO": img.save( output_file, format="ICO", sizes=[ (16, 16), (32, 32), (48, 48), (64, 64), (128, 128), (256, 256), ] ) if os.path.exists("__temp_png__.png"): os.remove("__temp_png__.png") original_kb = os.path.getsize(input_file) / 1024 final_kb = os.path.getsize(output_file) / 1024 print("Done!") print(f"Original size: {original_kb:.2f} KB") print(f"Output file: {output_file}") print(f"Output size: {final_kb:.2f} KB") if save_format == "JPEG": print(f"Final JPG quality: {quality}")

How to use it

  • Place your image in the same folder as the script (or anywhere — just type the full path. To copy image path: right click → Copy as path)
  • Double-click the script or run python image_resizer.py in terminal
  • Enter the filename — e.g. banner.png
  • Enter your target width and height in pixels
  • Choose png, jpg, ico or svg as output
  • Optionally enter a size limit like 1 for 1 MB — or just press Enter to skip

Example run

example
Enter image filename (e.g. photo.png): banner.png Output width (px): 1200 Output height (px): 630 Output format? png, jpg, ico or svg: ico Size limit in MB? Press Enter to skip: 1 Done! Original size : 3420.18 KB Saved as : banner_1200x630.ico Final size : 187.42 KB
The script always starts at maximum quality. It only reduces further if the file is still above your chosen size limit — so you always get the best result possible.
favicon example
Enter input image file name/path: logo.svg Output width (px): 256 Output height (px): 256 Output format? png, jpg, ico or svg: ico Done! Output file: logo_256x256.ico

SVG & ICO support

  • ICO: Useful for website favicons and app icons
  • SVG: Best for logos, icons and scalable graphics
  • The script can convert SVG files into PNG, JPG or ICO locally
  • The script can also attempt basic PNG/JPG to SVG tracing for simple shapes
PNG/JPG to SVG tracing works best for logos, icons and flat graphics. Complex photographs usually do not convert into clean SVG files automatically.

PNG vs JPG — which one to pick

  • PNG: Best for logos, icons, anything with transparency or sharp edges
  • JPG: Best for photos, banners, gradients, large images where file size matters
  • Converting a PNG to JPG alone often cuts the file size dramatically without visible quality loss
  • If a PNG is too large and you need it under a limit, JPG is almost always the answer

Why local beats online every time

Online image tools are everywhere and most of them work — technically. But they come with things you didn't sign up for: ads, upload limits, watermarks, quality loss you can't control, and files sitting on someone else's server. You also avoid uploading logos, app icons, branding files or client assets to random online converters.

This script has none of that. It runs in seconds, keeps your files exactly where they are, and gives you full control over dimensions, format, and compression. You don't need to understand the code. You just need to run it.

Sometimes the best tool is a small script you fully own — no account, no limit, no ads, no upload.

WordsByEkta🌿  ·  Found this useful? Share it with a creator who's still uploading to random sites.
Created by WordsByEkta🌿 — documenting real creator experiments in blogging, SEO, KDP publishing, AI-assisted app building, and technical troubleshooting.

Comments

Popular Posts

Stop Uploading PDFs Online — Unlock Them Yourself — WordsByEkta🌿

Publish Your Android App on Google Play Store — WordsByEkta🌿

How to Set Up Your Blogger About Me Page: Part 02 — WordsByEkta🌿