Install
$ agentstack add skill-prasad-nimbalkar-claude-agent-skills-image-resizer ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ● Filesystem access Used
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Image Resizer & Converter
Why this skill exists
Image processing has many silent failure modes: wrong aspect ratio, quality loss, wrong color mode for format (RGBA can't save as JPEG), and EXIF data stripping. This skill handles all of them correctly.
When to use
- User uploads an image and wants it resized, cropped, converted, or compressed
- User wants thumbnails, WebP conversion, or batch processing of a folder
Step-by-step procedure
Step 1 — Inspect the image first
from PIL import Image
import os
path = "/mnt/user-data/uploads/photo.jpg"
img = Image.open(path)
print(f"Format: {img.format}")
print(f"Mode: {img.mode}") # RGB, RGBA, L, P, etc.
print(f"Size: {img.size}") # (width, height)
print(f"File size: {os.path.getsize(path) / 1024:.1f} KB")
Step 2 — Resize (preserve aspect ratio)
from PIL import Image
def resize_image(input_path, output_path, max_width=None, max_height=None, exact_size=None):
img = Image.open(input_path)
if exact_size:
# Exact size — may distort
img = img.resize(exact_size, Image.LANCZOS)
elif max_width or max_height:
# Preserve aspect ratio
img.thumbnail(
(max_width or 99999, max_height or 99999),
Image.LANCZOS
)
# Fix mode before saving
output_format = output_path.rsplit(".", 1)[-1].upper()
if output_format == "JPG":
output_format = "JPEG"
if output_format == "JPEG" and img.mode in ("RGBA", "P"):
img = img.convert("RGB") # JPEG doesn't support transparency
img.save(output_path, format=output_format, quality=85, optimize=True)
print(f"Saved: {output_path} ({img.size[0]}×{img.size[1]})")
# Examples
resize_image("input.jpg", "output_800w.jpg", max_width=800)
resize_image("input.png", "thumbnail.png", max_width=200, max_height=200)
resize_image("input.jpg", "exact.jpg", exact_size=(1920, 1080))
Step 3 — Crop to square (thumbnail style)
def crop_to_square(input_path, output_path, size=512):
img = Image.open(input_path)
w, h = img.size
min_dim = min(w, h)
# Center crop
left = (w - min_dim) // 2
top = (h - min_dim) // 2
img = img.crop((left, top, left + min_dim, top + min_dim))
img = img.resize((size, size), Image.LANCZOS)
img.save(output_path)
print(f"Square crop saved: {output_path} ({size}×{size})")
Step 4 — Convert format
def convert_format(input_path, output_format="webp", quality=85):
img = Image.open(input_path)
base = input_path.rsplit(".", 1)[0]
output_path = f"{base}.{output_format}"
if output_format.lower() == "jpeg" and img.mode in ("RGBA", "P"):
img = img.convert("RGB")
img.save(output_path, format=output_format.upper(), quality=quality)
in_size = os.path.getsize(input_path) / 1024
out_size = os.path.getsize(output_path) / 1024
print(f"Converted: {output_path} ({in_size:.0f}KB → {out_size:.0f}KB)")
return output_path
Step 5 — Batch processing
import os
from pathlib import Path
def batch_resize(input_dir, output_dir, max_width=800):
Path(output_dir).mkdir(parents=True, exist_ok=True)
exts = {".jpg", ".jpeg", ".png", ".webp", ".gif", ".bmp"}
files = [f for f in Path(input_dir).iterdir() if f.suffix.lower() in exts]
print(f"Processing {len(files)} images...")
for i, file in enumerate(files, 1):
out = Path(output_dir) / file.name
resize_image(str(file), str(out), max_width=max_width)
print(f" [{i}/{len(files)}] {file.name}")
Edge cases
| Situation | Fix | |-----------|-----| | RGBA → JPEG error | img.convert("RGB") before saving as JPEG | | Palette mode (P) | img.convert("RGB") first | | Animated GIF | Use ImageSequence.Iterator — resizing just takes frame 0 | | EXIF rotation | ImageOps.exif_transpose(img) before resizing | | Very large image (>50MP) | Use Image.open with draft() to load at reduced size | | Output dir missing | os.makedirs(output_dir, exist_ok=True) |
Output format
Always report:
- Original dimensions and file size
- Output dimensions and file size
- Compression ratio (if converting/compressing)
- Output file path
Move final files to /mnt/user-data/outputs/ so the user can download them.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: prasad-nimbalkar
- Source: prasad-nimbalkar/claude-agent-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.