Watermark Image — add text or logo watermark, free in your browser
Stamp a copyright line, signature, or logo onto a JPG, PNG, or WebP photo entirely in your browser. Pick one of nine anchor positions, dial in size, opacity, rotation and margin, and download the result — files never leave your device.
How it works
A watermark is a small graphic — usually a copyright line, signature, or logo — painted on top of an image to attribute ownership or discourage uncredited reposting. On the web, that paint job is a three-step canvas operation that every modern browser supports natively. The tool above wires it up: decode the base photo into an HTMLImageElement, composite the watermark on top of it inside an off-screen canvas via fillText (text mode) or the 9-arg drawImage (image mode), then encode the canvas back to a file with canvas.toBlob. No part of either file leaves the tab.
The geometrically interesting step is placement. Given the base image, the (rendered) watermark's bounding box, an anchor from the nine-point grid, and a margin expressed as a fraction of the image's shorter axis, where exactly does the watermark's top-left corner land? The primary formula picks axes independently:
short_axis = min(image_width, image_height) margin_px = round(short_axis * margin_pct) # Column: left / centre / right if col == "left": x = margin_px elif col == "right": x = image_width - wm_width - margin_px else: x = round((image_width - wm_width) / 2) # Row: top / middle / bottom if row == "top": y = margin_px elif row == "bottom": y = image_height - wm_height - margin_px else: y = round((image_height - wm_height) / 2)
A second formula reaches the same result from the centre-frame — which is the reference frame the canvas translate / rotate calls work in. It computes the watermark centre first (the rotation pivot), then converts back to a top-left corner. Both formulas produce identical integer coordinates to within 1 px of rounding slack on every input the tool accepts. The Anchor row in the result tiles above shows the margin the geometry resolved to, so you can verify what shipped against the formula on your own image.
Text size scales with the photo's shorter axis so the same percentage produces a similar visual weight on portrait and landscape sources. A logo's width scales with the photo width, and the height is derived from the source aspect ratio so the logo never stretches. Opacity is applied via canvas globalAlpha; rotation pivots around the watermark's centre via translate → rotate → fillText/drawImage at (-w/2, -h/2).
Encoding uses the same path the Image Cropper tool relies on: canvas.toBlob(callback, mime, quality). JPEG quality is fixed at 0.92 — high enough that the photo under the watermark stays visually intact, low enough that the output file isn't larger than the input. PNG ignores the quality argument and is bit-perfect outside the watermark area; WebP is near-lossless at the same setting.
Worked examples
Anchor positions
Each chip on the position grid maps to one of nine fixed anchor points. The table below shows the top-left corner the geometry picks on a 1920 × 1080 base photo with a 240 × 70 px watermark bounding box and a 3 % margin — handy for predicting where your watermark will land before you upload anything.
| Anchor | Top-left (x, y) | Centre (cx, cy) |
|---|---|---|
| Top left | (32, 32) | (152, 67) |
| Top centre | (840, 32) | (960, 67) |
| Top right | (1,648, 32) | (1,768, 67) |
| Middle left | (32, 505) | (152, 540) |
| Centre | (840, 505) | (960, 540) |
| Middle right | (1,648, 505) | (1,768, 540) |
| Bottom left | (32, 978) | (152, 1,013) |
| Bottom centre | (840, 978) | (960, 1,013) |
| Bottom right | (1,648, 978) | (1,768, 1,013) |
Frequently asked questions
Sources & references
- MDN — CanvasRenderingContext2D.drawImage (9-arg source-rect form)
- MDN — CanvasRenderingContext2D.fillText (text watermark path)
- MDN — TextMetrics (canvas text bounding-box measurement)
- MDN — CanvasRenderingContext2D.rotate (pivot transforms)
- MDN — HTMLCanvasElement.toBlob (browser-native encoder)
- WIPO — Copyright basics (attribution and the © notice)
- WHATWG HTML — accept attribute on file inputs
Canvas behaviour and attribution conventions were last cross-checked against the above sources on 2026-05-11. The page is reviewed twice a year and whenever the WHATWG Canvas spec changes the drawImage / fillText contract.
Related tools
Comments & feedback
Spotted a bug or want an improvement? Tell us — our team reviews every comment, and good ideas get built. Comments are public and anonymous.
Found a bug, edge case, or want to suggest an improvement?
Email me at [email protected] — most fixes ship within 24 hours.