Old family photos fade and lose detail over time. Restoring them used to require hours of Photoshop work. With two AI APIs, you can automate the entire process: colorize a black and white photo, then enhance the faces.
The Pipeline
- Colorize: send the B&W photo to the Image Colorization API
- Enhance faces: pass the colorized result to the Face Restoration API
- Download: save the final restored image
The second API call uses the output URL from the first step directly. No need to download and re-upload.
Python Code
import requests
from pathlib import Path
API_KEY = "YOUR_API_KEY"
COLORIZE_URL = "https://photocolorizer-ai.p.rapidapi.com/colorize-photo"
RESTORE_URL = "https://face-restoration.p.rapidapi.com/enhance-face"
def restore_old_photo(image_path, output_path="restored.jpg"):
# Step 1: Colorize
with open(image_path, "rb") as f:
color_resp = requests.post(
COLORIZE_URL,
headers={
"x-rapidapi-key": API_KEY,
"x-rapidapi-host": "photocolorizer-ai.p.rapidapi.com",
},
files={"image": f},
)
colorized_url = color_resp.json()["image_url"]
# Step 2: Enhance faces
face_resp = requests.post(
RESTORE_URL,
headers={
"x-rapidapi-key": API_KEY,
"x-rapidapi-host": "face-restoration.p.rapidapi.com",
"Content-Type": "application/x-www-form-urlencoded",
},
data={"image_url": colorized_url, "mode": "all"},
)
restored = face_resp.json()
# Step 3: Download
img_data = requests.get(restored["image_url"]).content
Path(output_path).write_bytes(img_data)
return restored
result = restore_old_photo("grandma_1950.jpg")
print(f"Restored {result['faces_detected']} face(s)")
Why Two APIs?
Colorization and face restoration solve different problems. Colorization models predict what colors belong in a grayscale image. Face restoration models reconstruct facial features from low-quality inputs. Neither does the other's job. By chaining both, you get color and sharp faces in one pipeline.
Batch Processing
from concurrent.futures import ThreadPoolExecutor, as_completed
import os
def process_folder(input_dir, output_dir, max_workers=4):
os.makedirs(output_dir, exist_ok=True)
photos = [f for f in os.listdir(input_dir) if f.lower().endswith((".jpg", ".png"))]
with ThreadPoolExecutor(max_workers=max_workers) as pool:
futures = {
pool.submit(restore_old_photo, f"{input_dir}/{p}", f"{output_dir}/restored_{p}"): p
for p in photos
}
for fut in as_completed(futures):
print(f"Done: {futures[fut]}")
process_folder("old_photos/", "restored/")
Use Cases
- Genealogy apps: users upload old family photos, get colorized and enhanced versions
- Museum digitization: batch process historical photo archives
- Photo restoration SaaS: wrap the pipeline behind a web interface
👉 Read the full tutorial with before/after results and API vs GFPGAN comparison
Top comments (0)