Round Corners on Image — Rounded-Rect Path via WHATWG Canvas ctx.quadraticCurveTo() × 4 + ctx.clip()
Add smooth rounded corners to any image at the exact radius you choose (1-200 px adjustable via slider) via the WHATWG Canvas 2D Context's path-building primitives: 4 calls to `ctx.quadraticCurveTo(cpx, cpy, x, y)` (per html.spec.whatwg.org/#dom-context-2d-quadraticcurveto) build a rounded-rectangle sub-path with quadratic Bézier curves at each corner (control point at the rectangle's corner, endpoints at the radius-offset positions along the two adjacent edges), then `ctx.clip()` (per html.spec.whatwg.org/#dom-context-2d-clip) replaces the current clip region with the intersection of that rounded-rect path and the canvas extent. The subsequent `ctx.drawImage()` writes pixels only inside the clip region; the four corner regions outside the rounded mask become transparent (alpha=0). Output is always PNG (W3C 2nd Edition 10 November 2003 / ISO/IEC 15948:2004 with 8-bit per-pixel alpha) — JPG would render the transparent corners as a white or black background per the JPEG baseline's lack of alpha channel. Slider is debounced 100 ms to avoid expensive re-renders during drag. Files never leave the device.
How to round image corners
- Drop your image onto the tool. JPG, PNG, WebP, AVIF — any common raster format that the browser decodes natively works. Even JPG inputs produce a transparent PNG output (the rounded corners require alpha).
- Drag the radius slider. Small values (8-16 px) match typical CSS `border-radius` card UI styles; medium values (18-22 px on ~1242 px width) match iOS app-screenshot chamfer style; large values (60-120 px) create dramatic pill shapes; max 200 px.
- The tool builds the rounded-rect path via 4 ctx.quadraticCurveTo() calls + ctx.clip(), then draws the source image. The corners outside the rounded mask become transparent (alpha=0) in the canvas.
- Preview the result against the checkered transparency background to confirm the corner curves look smooth and the corner regions are transparent. The slider is debounced 100 ms — the preview updates ~100 ms after you release the slider.
- Click Download to save the PNG. The 8-bit alpha channel keeps the rounded corners transparent wherever you paste the image. Files never leave the device.
Common use cases
- Producing app-store screenshots with the platform-standard rounded corner radius (~18-22 px on 1242-wide iOS Marketing screenshots) without opening Sketch / Figma / Photoshop.
- Rounding avatars and profile pictures before uploading to platforms — gives control over the exact radius rather than relying on the platform's automatic crop.
- Preparing card imagery for web and landing pages so the PNG visual matches the CSS `border-radius` of your card components exactly (8-16 px is typical for modern card UIs).
- Softening photos for slide decks, pitch presentations, and pitch decks where the surrounding design uses rounded elements and sharp rectangular photos feel jarring.
- Creating pill-shaped or oval-cropped imagery for hero sections by setting radius close to min(width, height) / 2 — the rounded-rect approaches an oval as the radius approaches half the shorter side.
Frequently asked questions
Why is the output always PNG?
Rounded corners require an alpha channel to render the four corner regions as transparent. JPG (ITU-T T.81 baseline / JFIF v1.02) has no alpha channel — the would-be-transparent corner regions would render as pure white (default JFIF background) or whatever fill colour the canvas was initialised with. PNG (W3C 2nd Edition 10 November 2003 / ISO/IEC 15948:2004) preserves 8-bit alpha per pixel byte-exactly through `canvas.toBlob('image/png')`. If you need a JPG output with a solid coloured background instead of transparency, fill the canvas with the background colour before drawing — but the rounded-corner shape becomes a coloured-rounded-rect-on-coloured-rectangle appearance, no longer transparent.
Can I use this on a transparent PNG already?
Yes. The tool preserves any existing alpha channel in the source PNG and applies the rounded-rect mask on top via Canvas clip(). Transparent source pixels stay transparent in the output; the rounded mask only affects the four corner regions. Note that the clip() operation is multiplicative on alpha: if a source pixel has alpha=128 and falls inside the rounded mask, it stays alpha=128; if it falls outside the mask, it becomes alpha=0.
What radius should I use?
For CSS-card-matching UIs, copy your CSS `border-radius` value (commonly 8-16 px for modern web cards, 4-8 px for older Material-style cards). For iOS app-screenshot mocks on 1242-wide canvases, 18-22 px approximates iOS 7+ chamfer style (the exact iOS lock-screen/home-icon radius varies by device generation per Apple's Human Interface Guidelines). For dramatic pill/oval shapes, set radius close to min(width, height) / 2 — the rounded-rect path approaches an ellipse as radius → min(W,H)/2. Maximum slider value is 200 px.
Why quadraticCurveTo instead of arc?
Both work for rounded corners. The Canvas 2D Context's `arcTo(x1, y1, x2, y2, radius)` would also produce arcs at each corner; `quadraticCurveTo(cpx, cpy, x, y)` uses a quadratic Bézier curve with one control point. The two are visually nearly identical at small radii (≤30 px); at larger radii the quadratic Bézier deviates slightly from the perfect quarter-circle a true 90° arc would produce, producing slightly more 'squircle'-like corners. The implementation here uses quadraticCurveTo per the original tool author's choice; both spec-defined paths are valid per WHATWG html.spec.whatwg.org.
Is the original image modified?
No. The decode + ctx.quadraticCurveTo path build + ctx.clip + ctx.drawImage + toBlob('image/png') chain all runs client-side via WHATWG Canvas on a fresh in-memory canvas; the source file on disk is never modified. DevTools Network tab shows zero upload requests during conversion.
Canvas ctx.quadraticCurveTo() × 4-corner rounded-rect path + ctx.clip() + PNG alpha output
The round-corners pipeline builds the rounded-rectangle path via the WHATWG Canvas 2D Context's path-building primitives — 4 `quadraticCurveTo()` calls at the corners interleaved with `lineTo()` along the straight edges per html.spec.whatwg.org/#dom-context-2d-quadraticcurveto. The path sequence is: `beginPath()` → `moveTo(radius, 0)` (top edge start, post-corner) → `lineTo(width - radius, 0)` (top edge end, pre-corner) → `quadraticCurveTo(width, 0, width, radius)` (top-right corner, control at the rectangle's top-right vertex, curve endpoint radius pixels down the right edge) → `lineTo(width, height - radius)` (right edge) → `quadraticCurveTo(width, height, width - radius, height)` (bottom-right corner) → `lineTo(radius, height)` (bottom edge) → `quadraticCurveTo(0, height, 0, height - radius)` (bottom-left corner) → `lineTo(0, radius)` (left edge) → `quadraticCurveTo(0, 0, radius, 0)` (top-left corner) → `closePath()`. Then `clip()` replaces the current clip region with the intersection of this rounded-rect path and the canvas extent per html.spec.whatwg.org/#dom-context-2d-clip. The subsequent `drawImage(source, 0, 0)` writes the source image to the canvas; pixels inside the rounded-rect mask survive, pixels in the four corner regions outside the mask remain at alpha=0 (the canvas was freshly allocated with RGBA all-zero state). Output is `canvas.toBlob('image/png')` per WHATWG — PNG preserves the alpha channel byte-exactly (W3C PNG 2nd Edition 10 November 2003). JPG is unavailable because the JPEG baseline (ITU-T T.81 1992) has no alpha channel — the rounded corner regions would render as JFIF default white (0xFFFFFF) or whatever fill colour. The slider control is debounced via setTimeout 100 ms to coalesce rapid drag events into a single re-render. Common radius values: card UIs use 8-16 px to match CSS `border-radius`; iOS app-screenshot mocks use 18-22 px on ~1242 px width to match iOS 7+ chamfer style; pill / oval shapes use radius approaching min(width, height) / 2 (≥100 px on typical photo dimensions).
- Adjustable corner radius 1-200 pixels via slider (debounced 100 ms to coalesce drag events)
- WHATWG Canvas ctx.quadraticCurveTo() × 4-corner rounded-rect path per html.spec.whatwg.org/#dom-context-2d-quadraticcurveto with ctx.clip() per html.spec.whatwg.org/#dom-context-2d-clip
- PNG output (W3C 2nd Edition 10 November 2003 / ISO/IEC 15948:2004) with 8-bit per-pixel alpha — transparent corners preserved byte-exactly
- Quadratic Bézier corner curves (control point at the rectangle's vertex, endpoints radius-offset along the two adjacent edges) — sharper than a 90° arc for the same radius
- Anti-aliased corner edge from the Canvas 2D Context rasteriser (spec leaves rasteriser quality implementation-defined; modern browsers anti-alias to sub-pixel accuracy)
- Preserves the source resolution and colour data 1:1 — only pixels in the four corner regions outside the rounded-rect mask are discarded
- Browser-side via WHATWG Canvas quadraticCurveTo + clip + drawImage + toBlob('image/png') — no upload
- Operates in sRGB (IEC 61966-2-1:1999); source images without an embedded ICC profile are interpreted as sRGB
Free. No signup. No file uploads. Ads via AdSense (consent required).
Sources (9)
- WHATWG (live). HTML Living Standard — Canvas 2D Context: quadraticCurveTo(cpx, cpy, x, y). html.spec.whatwg.org/#dom-context-2d-quadraticcurveto — the rounded-corner path-building primitive: connects the last point in the current sub-path to (x, y) using a quadratic Bézier curve with control point (cpx, cpy); the round-corners tool calls quadraticCurveTo four times (one per corner) with control point at the rectangle's corner vertex and endpoints radius-offset along the two adjacent edges, interleaved with lineTo() calls along the straight edges.
- WHATWG (live). HTML Living Standard — Canvas 2D Context: clip(). html.spec.whatwg.org/#dom-context-2d-clip — replaces the current clip region with the intersection of the current path and the canvas extent; subsequent drawImage writes pixels only inside the rounded-rect mask, leaving the four corner regions at the default RGBA all-zero (transparent) state.
- WHATWG (live). HTML Living Standard — Canvas 2D Context: drawImage(). html.spec.whatwg.org/#dom-context-2d-drawimage — the 3-argument form drawImage(source, 0, 0) writes the source image at native dimensions to the canvas; pixels falling inside the clip region survive, pixels outside remain transparent.
- W3C (PNG Working Group) (2003). Portable Network Graphics (PNG) Specification (Second Edition). W3C Recommendation 10 November 2003 / ISO/IEC 15948:2004 — the only output format that preserves the alpha channel byte-exactly (8-bit alpha per RGBA pixel); required for the transparent corner regions.
- WHATWG (live). HTML Living Standard — HTMLCanvasElement.toBlob('image/png'). html.spec.whatwg.org/#dom-canvas-toblob — re-encodes the canvas pixel buffer to a PNG Blob with the alpha channel preserved.
- WHATWG (live). HTML Living Standard — HTMLImageElement (browser-native raster decoding). html.spec.whatwg.org/#htmlimageelement — universal browser entry point for source raster format decode.
- ITU-T (CCITT) Study Group VIII & ISO/IEC JTC 1/SC 29/WG 10 (JPEG) (1992). Information technology — Digital compression and coding of continuous-tone still images: Requirements and guidelines. ITU-T Recommendation T.81 (18 September 1992) / ISO/IEC 10918-1:1994 — JPEG baseline DCT bitstream; cited in the round-corners docs as the reason JPG output is unavailable (the baseline JPEG has no alpha channel for the rounded corner regions).
- Hamilton, E. (C-Cube Microsystems) (1992). JPEG File Interchange Format (JFIF) Version 1.02. 1 September 1992 — JPEG container format; the baseline-JPEG JFIF v1.02 default-white background is what would render in place of the rounded corner regions if JPG were used as the output format.
- International Electrotechnical Commission (IEC) (1999). Multimedia systems and equipment — Colour measurement and management — Part 2-1: Default RGB colour space — sRGB. IEC 61966-2-1:1999 — default 8-bit RGB colour space the Canvas 2D path operates in.
These are the W3C, ISO/IEC, ITU-T, and IETF specifications the tool implements or builds on. Locate them on w3.org, iso.org, itu.int, or datatracker.ietf.org.
By Marco B. ·