Clone Stamp

Classic clone brush. Pick a source point in a clean part of the image, then paint that source into a target area with a feathered brush. The source follows the cursor at a locked offset for the duration of each stroke, so you can repair along curved paths (galaxy arms, nebula filaments) while sampling a parallel stretch of similar structure. Useful for anything the one-click Blemish Blaster can't handle on its own: large irregular defects, star field continuations, satellite trail patches on textured background, and any time you want manual control over which pixels get used as the heal source.

1. Workflow in a nutshell

  1. Hold Ctrl and left-click on a clean part of the image. A green X marks the source.
  2. Release Ctrl. Move the cursor to the area you want to repair — a green circle at the current brush size follows.
  3. Left-click and drag. The offset between target and source locks on the first click of the stroke; from then on, a green X tracks the live source position with a dotted line linking source and brush.
  4. Release. Zoom and inspect. Undo with Ctrl+Z if the stroke isn't right.
  5. Repeat with new strokes (same or different source) until the repair looks seamless, then Apply to Document.

2. Setting the source

Ctrl+left-click anywhere in the image sets the source point. A solid green X is drawn at that location so you can see what you've picked. The source persists until you Ctrl+click somewhere else or press Clear Source; it survives between strokes, mode changes, zoom and pan.

Each stroke captures the source–target offset at its first click — so the X marker you see while painting isn't the original Ctrl+click point, it's the live source position offset from your current cursor by that captured amount. This is the classical Photoshop clone-stamp behaviour: start the stroke where you want the fix to begin, and the source tracks along at the same relative offset.

3. Painting

Once a source is set, a plain left-click (no Ctrl) starts a stroke. Dragging continues it. Releasing ends it. A dotted green line links the brush to its live source position while the stroke is active, so you can always see where the next dab is being sampled from.

Dabs are placed at regular intervals along the drag path to keep the stroke smooth; the spacing is ¼ of the brush radius, so large brushes dab less often (fewer but bigger) and small brushes dab tightly along the path. Each dab's source position is computed from the stroke-wide offset — so if the source approaches the image edge mid-stroke, the dabs quietly skip over the out-of-bounds part rather than filling it with black.

4. Visual overlays

5. Brush controls

Radius / Feather / Opacity

Brush preview chip

The 90×90 preview to the right of the sliders shows the current mask at the live radius/feather/opacity values. Watching this while adjusting feather is the quickest way to understand what the brush will do before you click — the chip renders the exact mask that will be multiplied into the image.

Clear Source

Dismisses the current source point so Ctrl+click is needed again before the next stroke. Doesn't affect the painted result — only the source marker.

6. Auto-stretch preview

Off by default. When on, a statistical stretch is applied to the preview buffer only; the underlying image data (and the undo/redo state) is never modified by this control. Essential for working on linear data where a defect would otherwise be invisible against the background.

Both stretched and non-stretched display buffers are kept in sync during painting so toggling the checkbox is instant — no need to wait for a re-stretch of the whole image.

7. Zoom and pan

Toolbuttons for Zoom Out, Zoom In, Fit to Preview. Mouse wheel and trackpad zoom with the cursor as the anchor — small trackpad swipes fine, click-wheel detents coarse, hold Ctrl to zoom faster in either case. Range 0.05× to 4×. The preview auto-fits on first open; after that your zoom and pan state is preserved across all operations in the session.

8. Undo / Redo / Apply

Each complete stroke (down–drag–up) is one undo entry, regardless of how many dabs it contained. The ring holds up to 20 strokes. Ctrl+Z and Ctrl+Y undo/redo as usual (bound as actions on the dialog itself so they take priority when the dialog has focus).

Apply to Document commits the current working image back to the originating document as a single edit named “Clone Stamp” and closes the dialog. Mono originals are automatically collapsed back to a single plane; RGB sources stay RGB. Close discards everything. The dialog's window geometry is persisted per-user and restored on next open.

9. Keyboard shortcuts

10. Technical details

All processing on float32 [0, 1]. The dialog displays a 3-channel copy of the working image regardless of source depth; on Apply, mono originals are collapsed back to a single plane.

10.1 Brush mask

The brush is a circular disk with a feathered falloff ring at the edge. With radius r and feather fraction f ∈ [0, 1], the inner hard-disk radius is:

r_{\mathrm{inner}} \;=\; r\,(1 - f)

Everything inside rinner has weight 1; between rinner and r the weight falls off linearly to zero at the edge:

w(d) \;=\; \mathrm{clip}\!\left(\frac{r - d}{r\,f},\;0,\;1\right)\;\;\mathrm{for}\;\;d \leq r

where d is the Euclidean distance from the brush centre. At f = 0 the formula collapses to a hard disk (the r·f denominator special-cases to a step at d = r); at f = 1 it ramps linearly from the brush centre to the edge. The resulting mask is cached by its (r, f) key as a NumPy array, so subsequent dabs with the same parameters reuse the same buffer without rebuilding it.

10.2 Dab placement along a stroke

During a drag from p0 to p1, dabs are placed at a fixed spacing proportional to the brush radius:

\Delta_{\mathrm{dab}} \;=\; \max(1,\;0.25\,r)
n \;=\; \max\!\left(1,\;\left\lfloor\frac{\|\mathbf{p}_1 - \mathbf{p}_0\|}{\Delta_{\mathrm{dab}}}\right\rfloor\right)

then n dabs are linearly interpolated along the segment. The ¼-radius spacing is the standard Photoshop default — dense enough that the overlapping dab masks sum to a flat stroke, sparse enough that huge brushes don't thrash the CPU.

10.3 Source-follow offset

When a stroke starts at target position (tx(0), ty(0)) with source at (sx, sy), the offset is captured and locked for the whole stroke:

(o_x,\,o_y) \;=\; (s_x - t_x^{(0)},\;s_y - t_y^{(0)})

Each subsequent dab at target position i samples from:

(s_x^{(i)},\,s_y^{(i)}) \;=\; (t_x^{(i)} + o_x,\;t_y^{(i)} + o_y)

which is the signature behaviour of a classical clone brush: as you drag the cursor, the sampled source traces a parallel path. Starting a new stroke captures a new offset based on wherever the stroke begins, so moving to a new target area doesn't drag the source along with you until you click to begin painting.

10.4 Blend formula

Per dab, the final per-pixel alpha combines mask weight and opacity, and the result is a straight linear blend:

\alpha \;=\; w \,\cdot\, \mathrm{opacity}\,,\qquad \mathrm{out} \;=\; (1 - \alpha)\,\mathrm{target} \;+\; \alpha\,\mathrm{source}

applied in place on all three display channels. Source and target rectangles are clipped against the image bounds jointly: if either falls off the edge, the visible intersection is painted and the invisible part is skipped, so a brush that straddles the border still paints its in-bounds half without pulling in bogus zeros from off-image.

10.5 Tile-based stroke undo

Snapshotting the entire image on every stroke is expensive and wasteful — most strokes touch a tiny fraction of the frame. The dialog partitions the image into 64×64 tiles and tracks which tiles each stroke has modified:

The result: a 20-pixel dab in a 6000×4000 frame costs one 64×64 patch to undo (16 KB), not the entire frame (288 MB). A long freehand stroke that traverses several tiles pays only for those tiles once each, regardless of how many dabs crossed them.

10.6 Display buffers and throttled refresh

The dialog keeps three identical-shape float32 buffers in sync: _image (authoritative), _display_raw (what auto-stretch-off shows), and _display_stretched (what auto-stretch-on shows). Each dab is applied in place to all three, so toggling the auto-stretch checkbox swaps between them with no latency.

During a drag, repainting the whole scene on every mouse-move event would starve the paint loop, so refresh is throttled to ~30 fps via a 33 ms single-shot timer: the first dab schedules a refresh, subsequent dabs within the window are coalesced into that pending refresh, and the preview catches up smoothly without flooding Qt's event queue.