---
title: "How to add a color replace with Claude (tested prompt and script)"
description: "At 1 second the purple serum fades to amber orange inside its glass, while the pastel holographic backdrop and clear block keep their original colors. Install one skill and ask Claude Code, or run the Python script we tested yourself."
url: https://www.recharm.com/effects/color-replace
---

# How to add a color replace with Claude

At 1 second the purple serum fades to amber orange inside its glass, while the pastel holographic backdrop and clear block keep their original colors.

Made by the script on this page, from our own test clip.

## Get this effect

1. ### Switch to Code in your [Claude Desktop App](https://claude.com/download)

2. ### Install the skill (once)

   ```
   Install the Recharm video effects skill: download https://recharm-growth-staging.s3.us-east-2.amazonaws.com/website/downloads/recharm-video-effects.zip and unzip it into ~/.claude/skills
   ```

3. ### Ask for the effect

   ```
   Add a color replace to input.mp4
   Hue range to replace, on OpenCV's 0-180 scale: (118, 158)
   Pixels less saturated than this keep their color, so pale tints of the same hue are left alone: 60
   ```

## Several videos, several effects, one ask

Put your clips in the folder, mention them with @, and ask for everything at once. Claude runs one tested script after another on each clip, then joins them.

Add a color replace to **@clip1.mp4**, put a sale badge on **@clip2.mp4**, give **@clip3.mp4** a VHS look, then join all three with crossfades.

## Settings you can change

Ask Claude to change any of these, or edit them at the top of the script.

| Setting     | Default      | What it does                                                                                    |
| ----------- | ------------ | ----------------------------------------------------------------------------------------------- |
| `FROM_HUE`  | `(118, 158)` | Hue range to replace, on OpenCV's 0-180 scale. 118-158 is the bottle's purple.                  |
| `MIN_SAT`   | `60`         | Pixels less saturated than this keep their color, so pale tints of the same hue are left alone. |
| `SOFT`      | `8`          | How gradually the mask fades at the edges of the hue and saturation ranges.                     |
| `TO_HUE`    | `18`         | The new hue, 0-180. 18 is amber orange; 60 is green, 100 blue.                                  |
| `SAT_BOOST` | `1.6`        | Saturation multiplier on the new color. 1 keeps the original strength.                          |
| `START`     | `1.0`        | Second the new color starts fading in. 0 replaces it from the first frame.                      |
| `FADE`      | `0.4`        | Seconds the change takes.                                                                       |

## Without the skill

Don’t want to install the skill? Paste this prompt into Claude Code and Claude writes the script itself.

```
In input.mp4, replace the bottle's purple with amber orange using Python and OpenCV. Convert each frame to HSV (OpenCV scale, hue 0-180) and select pixels with hue between 118 and 158 and saturation above 60, fading the mask over 8 units at both edges and blurring it with a 5x5 Gaussian so the edges don't band. In those pixels set the hue to 18 (amber orange) and multiply the saturation by 1.6, keeping the brightness. Leave the first second untouched, then fade the new color in from 1.0 to 1.4 seconds and keep it to the end. Everything less saturated, like the pale lilac backdrop, keeps its color. No text is drawn (if you add any, draw it with Pillow, not ffmpeg's drawtext). Keep the size, 30fps, the 6-second length and the audio, and save it as output.mp4.
```

## Run it without Claude

This is the exact script we tested. Save it as `color-replace.py` and run:

```
python3 color-replace.py input.mp4 output.mp4
```

```
#!/usr/bin/env python3
"""Color replace: at 1 second the purple bottle turns amber orange while the pastel backdrop keeps its colors.

Usage: python3 color-replace.py input.mp4 output.mp4
Needs ffmpeg, OpenCV and numpy (pip install opencv-python-headless numpy).
"""
import subprocess
import sys

import cv2
import numpy as np

FROM_HUE = (118, 158)   # hue range to replace, OpenCV scale 0-180 (here the bottle's purple, 236-316 degrees)
MIN_SAT = 60            # pixels less saturated than this keep their color (the pale lilac backdrop)
SOFT = 8                # hue and saturation units over which the mask fades, so edges don't band
TO_HUE = 18             # new hue, 0-180 (18 = amber orange, 36 degrees)
SAT_BOOST = 1.6         # saturation multiplier on the replaced color
START = 1.0             # second the new color starts fading in
FADE = 0.4              # seconds the change takes

def mask_of(hsv):
    """0-1 weight per pixel: how much it belongs to the color being replaced."""
    h, s = hsv[..., 0].astype(np.float32), hsv[..., 1].astype(np.float32)
    in_hue = np.clip(np.minimum(h - FROM_HUE[0], FROM_HUE[1] - h) / SOFT + 0.5, 0, 1)
    in_sat = np.clip((s - MIN_SAT) / SOFT + 0.5, 0, 1)
    return cv2.GaussianBlur(in_hue * in_sat, (5, 5), 0)[..., None]

def recolor(frame, amount):
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    swapped = hsv.copy()
    swapped[..., 0] = TO_HUE
    swapped[..., 1] = np.clip(hsv[..., 1] * SAT_BOOST, 0, 255)
    new = cv2.cvtColor(swapped, cv2.COLOR_HSV2BGR).astype(np.float32)
    weight = mask_of(hsv) * amount
    return (frame * (1 - weight) + new * weight).astype(np.uint8)

src, out = sys.argv[1:3]
video = cv2.VideoCapture(src)
fps = video.get(cv2.CAP_PROP_FPS)
w, h = int(video.get(cv2.CAP_PROP_FRAME_WIDTH)), int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
ff = subprocess.Popen(["ffmpeg", "-y", "-v", "error", "-f", "rawvideo", "-pix_fmt", "bgr24", "-s", f"{w}x{h}",
                       "-r", str(fps), "-i", "-", "-i", src, "-map", "0:v", "-map", "1:a?", "-shortest",
                       "-c:v", "libx264", "-crf", "18", "-pix_fmt", "yuv420p", "-c:a", "copy", out],
                      stdin=subprocess.PIPE)
i = 0
while True:
    ok, frame = video.read()
    if not ok:
        break
    amount = min(max((i / fps - START) / FADE, 0), 1)
    ff.stdin.write((recolor(frame, amount) if amount else frame).tobytes())
    i += 1
ff.stdin.close()
if ff.wait():
    sys.exit("ffmpeg failed")
```

## More color looks

- [Apply a LUT **Apply a LUT**](https://www.recharm.com/effects/apply-a-lut)
- [Black and white **Black and white**](https://www.recharm.com/effects/black-and-white)
- [Bleach bypass **Bleach bypass**](https://www.recharm.com/effects/bleach-bypass)
- [Cinematic color grade **Cinematic color grade**](https://www.recharm.com/effects/cinematic-color-grade)
- [Color match **Color match**](https://www.recharm.com/effects/color-match)

## Find 3x _winning ads_

Recharm cuts your ad footage into tagged, searchable clips: hooks, testimonials, product shots. Find the shots that win, add the effect with Claude, and ship 3x more ad edits.

[Start 14-day free trial](https://www.recharm.com/get-started)
