Most image-to-video tools publish input limits, and most people ignore them until an upload fails. If you're helping friends make a short AI video from their photos, a quick local check saves a lot of "why won't it take my picture?" messages.
This post walks through a small Python script that checks a folder of photos against a published set of limits, fixes the two problems you can fix automatically (orientation and file size), and flags the rest. I'll use the limits published by GangnamStyleAIVideo.org, a single-purpose web tool for the Gangnam Style AI trio trend, because they are documented clearly in its llms.txt. The same approach works for any tool; just change the constants.
The limits we're checking
As published on the site (facts dated 2026-10-26), each video takes three photos, one person each, or one group photo of all three. Each file must be:
- JPG, PNG or WebP
- up to 4 MB
- 300 to 5760 px per side
- a width-to-height ratio between 0.4 and 2.5
Photos only: no video, audio or text input. Those four rules are mechanical, so a script can check them.
Setup
You only need Pillow:
python3 -m pip install Pillow
The script
# preflight.py: check photos against an upload spec
import sys
from pathlib import Path
from PIL import Image, ImageOps
ALLOWED = {"JPEG", "PNG", "WEBP"}
MAX_BYTES = 4_000_000 # stricter reading of "4 MB"
MIN_SIDE, MAX_SIDE = 300, 5760
MIN_RATIO, MAX_RATIO = 0.4, 2.5
def check(path: Path) -> list[str]:
problems = []
size = path.stat().st_size
if size > MAX_BYTES:
problems.append(f"file is {size/1e6:.1f} MB (max 4 MB)")
with Image.open(path) as im:
if im.format not in ALLOWED:
problems.append(f"format {im.format} not accepted")
im = ImageOps.exif_transpose(im) # size as it will display
w, h = im.size
if min(w, h) < MIN_SIDE or max(w, h) > MAX_SIDE:
problems.append(f"{w}x{h} px is outside {MIN_SIDE}-{MAX_SIDE} px")
ratio = w / h
if not MIN_RATIO <= ratio <= MAX_RATIO:
problems.append(f"ratio {ratio:.2f} outside {MIN_RATIO}-{MAX_RATIO}")
return problems
def fix(path: Path, out_dir: Path) -> Path:
"""Bake in orientation, cap the long side, save as JPEG."""
out_dir.mkdir(exist_ok=True)
with Image.open(path) as im:
im = ImageOps.exif_transpose(im).convert("RGB")
im.thumbnail((2048, 2048))
target = out_dir / (path.stem + ".jpg")
im.save(target, "JPEG", quality=90)
return target
if __name__ == "__main__":
folder = Path(sys.argv[1])
for p in sorted(folder.iterdir()):
if p.is_dir():
continue
try:
issues = check(p)
except Exception as e: # not an image at all
print(f"SKIP {p.name}: {e}")
continue
if not issues:
print(f"OK {p.name}")
continue
print(f"FIX {p.name}: {'; '.join(issues)}")
fixed = fix(p, folder / "fixed")
left = check(fixed)
print(f" -> {fixed.name}: {'OK' if not left else '; '.join(left)}")
Run it with python3 preflight.py ./photos.
Why each step is there
exif_transpose. Phones often save a portrait photo as a landscape image with an orientation tag. If you measure the raw pixels, you get the ratio backwards. Applying the EXIF rotation first means you check the image the way people actually see it, and the fixed copy has the rotation baked in, so nothing downstream has to interpret the tag.
The 4,000,000-byte limit. "4 MB" can mean 4,000,000 bytes or 4 × 1024 × 1024. I don't know which one the server uses, so the script takes the stricter one. A false warning costs nothing; a rejected upload on mobile is annoying.
thumbnail((2048, 2048)). A modern phone photo can be 4000 px or more on the long side and well over 4 MB. Capping the long side at 2048 keeps it far inside both the size and pixel limits while staying sharp enough for a face reference. thumbnail keeps the aspect ratio and never upscales.
What the script can't fix. If an image is under 300 px on a side or has an extreme ratio (a screenshot of a chat, a panorama), resizing won't help. You need a different photo, so the script reports it and moves on rather than guessing a crop.
The checks a script can't do
The mechanical rules are the easy part. For this kind of trio video, the published guidance also asks for things you have to check by eye:
- One person per photo, face toward the camera; chest up is enough. If you use a single group photo instead, it should show exactly three people side by side with every face visible and nobody else in the frame.
- Order matters. The tool reads a group photo left to right, and the person in the middle holds the phone and sings first. With separate photos, each friend has their own slot (middle, left, right), so decide who goes in the middle before uploading.
- Consent. Everyone in the photos must be you or an adult who agreed to be in the video. Photos of celebrities or public figures are not allowed, and the site asks you to confirm consent before it renders.
Put those three items in the message asking friends for their photos.
Running it before you pay
The tool has no free tier; a 19-second Standard 480p video costs 100 credits, and the smallest pack is $9.99 for 100 credits. If a render fails, the credits go back to your balance automatically, but it's still nicer to get the inputs right the first time. The output is a 16:9 MP4 with an original beat, so plan to add the trend sound in TikTok when you post.
The script is small on purpose: copy it, swap the constants for whatever tool you're using, and run it on the folder your friends' photos landed in. If you want the generator itself, it's at https://gangnamstyleaivideo.org/.
This article was written with AI assistance.
Top comments (0)