Skip to content

Image Filters Online

Browser-side — no upload
Last verified May 2026 — runs in your browser

Image Filters — 4 Hardcoded Per-Pixel RGB Curve Presets via Canvas ImageData per-pixel Loop

Apply one of 4 hardcoded artistic filter presets to any photo via per-pixel Canvas ImageData manipulation. The presets are: Vintage (R × 1.1 + 20, G × 0.9 + 10, B × 0.8 — warm-shifted with reduced blue), Noir (BT.601 luma `Y = 0.299R + 0.587G + 0.114B` → high-contrast threshold at 128: Y > 128 maps to Y × 1.2, Y ≤ 128 maps to Y × 0.8 — produces high-contrast grayscale), Warm (R + 15, G + 5, B − 10 — channel-shift toward orange-red), Cool (R − 10, G + 5, B + 20 — channel-shift toward blue). Each filter is a single Canvas ImageData pass that runs `for (i = 0; i < data.length; i += 4) { ... }` over the Uint8ClampedArray buffer, applying the per-channel arithmetic with `Math.min(255, ...)` / `Math.max(0, ...)` clamping. Note: this is NOT the CSS `filter` property (which composes blur / brightness / contrast / hue-rotate / sepia / saturate / invert / grayscale primitives at the render layer) — this tool applies 4 specific hardcoded RGB curves to the pixel buffer at export time. Output preserves source format: PNG → PNG (RGBA alpha preserved); JPG → JPG quality 0.92 via canvas.toBlob (ITU-T T.81 Annex K perceptual quantisation). Files never leave the device.

How to apply an image filter

  1. Drop a photo onto the tool or click to browse. Any common raster format the browser decodes natively works (JPG, PNG, WebP, AVIF).
  2. Click through the 4 preset buttons. The preview updates immediately on each click — Vintage (warm faded), Noir (high-contrast black-and-white), Warm (orange shift), Cool (blue shift).
  3. Pick the filter that matches the mood you want. Each preset applies fixed per-channel arithmetic — no strength slider in the current implementation.
  4. Download the filtered copy. Output format preserves the source (PNG → PNG with alpha, JPG → JPG quality 0.92).
  5. For more control (strength, brightness, contrast, saturation), use a dedicated colour-grading tool. For finer artistic stacks, layer multiple passes manually — download a filtered output and re-upload to apply a second preset on top.

Common use cases

  • Giving a batch of holiday or travel photos a consistent look before posting them as a cohesive album on Instagram, Twitter/X, or a blog.
  • Adding drama to portraits via the Noir preset for a high-contrast black-and-white editorial feel without manual curve adjustment.
  • Warming up overcast-day photos via the Warm preset so they feel more inviting on a blog, travel site, or product listing.
  • Cooling down daylight shots via the Cool preset to signal a winter, night, or moody atmosphere in marketing creatives and thumbnails.
  • Producing a single-look preview for a colour-grading mood board before committing to a more detailed colour-correction workflow in a dedicated tool.

Frequently asked questions

Is this the CSS `filter` property?

No. CSS `filter` composes blur / brightness / contrast / hue-rotate / sepia / saturate / invert / drop-shadow / grayscale primitives at the render-layer compositing stage per WHATWG html.spec.whatwg.org. This tool applies 4 specific hardcoded RGB curves directly to the pixel buffer at export time via Canvas ImageData manipulation — the result is baked into the downloaded image bytes, not applied at display time. For CSS-filter-style render-layer effects, use the CSS `filter` property on the source HTML element before exporting via a html-to-image library.

Can I tweak the strength of a filter?

No — the current implementation applies each preset at a fixed strength with no slider control. For partial-strength effects, you can chain the output with an additional pass in an image editor (load the filtered output, blend with the original at reduced opacity). The 4 preset functions are fixed arithmetic; modifying the strength would require editing the per-channel multipliers and offsets in the component source.

Can I stack multiple filters?

Not in one pass — but you can download a filtered image and run it through the tool again with a different preset to layer looks. Each pass is a fresh transform, so results may soften slightly with repeated JPG saves (the canvas.toBlob re-encode applies ITU-T T.81 Annex K perceptual quantisation at quality 0.92 each pass, accumulating ~1-2% loss per round-trip). For lossless stacking, use PNG sources.

Does the filter change image dimensions?

No. The per-pixel ImageData loop modifies the RGB values but not the canvas dimensions — output is bit-exact pixel-for-pixel with the source dimensions. File size may change slightly because different colour distributions compress differently (e.g. the Noir preset's near-grayscale output compresses ~10-20% smaller for PNG via DEFLATE redundancy).

Are my images uploaded?

No. The decode + ctx.getImageData + per-pixel preset function + ctx.putImageData + canvas.toBlob chain all run client-side via WHATWG Canvas. DevTools Network tab shows zero upload requests during conversion.

4 hardcoded RGB curve presets + per-pixel Canvas ImageData manipulation

The tool applies one of 4 hardcoded per-pixel RGB curve presets via Canvas ImageData manipulation. Each preset is a small JavaScript function that iterates the Uint8ClampedArray returned by `ctx.getImageData()` in stride-4 (R, G, B, A per pixel) and applies the per-channel arithmetic with clamping. The four presets: Vintage — `R = min(255, R × 1.1 + 20); G = min(255, G × 0.9 + 10); B = min(255, B × 0.8)` — boosts red, slightly reduces green, significantly reduces blue, producing a warm faded look reminiscent of aged Kodachrome prints. Noir — first computes `Y = 0.299R + 0.587G + 0.114B` (the ITU-R BT.601 luma per the cluster 15 OI grayscale-image standard), then applies a high-contrast threshold: `Y > 128 → min(255, Y × 1.2)`, `Y ≤ 128 → Y × 0.8`, writing the result to all three R/G/B channels — produces a high-contrast black-and-white look with crushed shadows and elevated highlights. Warm — `R += 15; G += 5; B -= 10` (with clamping to [0, 255]) — channel-shifts the entire image toward orange-red without modifying the per-channel curve shape. Cool — `R -= 10; G += 5; B += 20` (with clamping) — channel-shifts toward blue. Critical note — this tool is NOT the CSS `filter` property (which composes blur, brightness, contrast, hue-rotate, sepia, saturate, invert, drop-shadow, and grayscale primitives at the render-layer compositing stage per html.spec.whatwg.org). This tool applies 4 specific hardcoded RGB curves to the actual pixel buffer at export time via Canvas ImageData manipulation. The per-channel transforms here are NOT spec-derived (no industry standard recipe for 'vintage' or 'cool' colour grading); they're hand-tuned constants matching common social-media filter aesthetics. For finer control over brightness, contrast, saturation, hue, or saturation, use a dedicated colour-grading tool (or chain CSS `filter` primitives on the HTML element before exporting via html-to-image or similar). Output preserves source format: PNG sources stay PNG with RGBA alpha; JPG sources output JPG at quality 0.92 via canvas.toBlob (ITU-T T.81 Annex K perceptual quantisation, approximately 1-2% perceptually invisible additional loss versus the source).

  • Four hardcoded per-pixel RGB curve presets: Vintage (R × 1.1 + 20, G × 0.9 + 10, B × 0.8) + Noir (BT.601 luma + high-contrast threshold at 128) + Warm (R + 15, G + 5, B − 10) + Cool (R − 10, G + 5, B + 20)
  • Per-pixel Canvas ImageData manipulation via WHATWG ctx.getImageData + Uint8ClampedArray for-loop + ctx.putImageData
  • NOT the CSS `filter` property — these are hardcoded RGB curves applied to the pixel buffer at export time, not render-layer compositing primitives
  • Hand-tuned channel arithmetic constants (no industry-standard recipe for 'vintage' / 'noir' / 'warm' / 'cool' — these are common social-media filter aesthetics)
  • Toggle through the 4 presets via tab buttons; preview updates immediately on click
  • Preserves source format: PNG → PNG with RGBA alpha; JPG → JPG quality 0.92 (ITU-T T.81 Annex K)
  • Browser-side via WHATWG Canvas ImageData + per-pixel arithmetic + canvas.toBlob — 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)
  • International Telecommunication Union (ITU-R, formerly CCIR) (1982). ITU-R BT.601 — Luma formula underlying the Noir preset. itu.int/rec/R-REC-BT.601 — the Noir preset first computes `Y = 0.299R + 0.587G + 0.114B` per BT.601 (cluster 15 OI grayscale standard), then applies a high-contrast threshold at 128: Y > 128 → Y × 1.2; Y ≤ 128 → Y × 0.8. The BT.601 coefficients derive from the NTSC YIQ colour encoding (FCC docket 9019, ratified 17 December 1953) and were codified by the CCIR in BT.601 in 1982.
  • WHATWG (live). HTML Living Standard — Canvas 2D Context: getImageData(). html.spec.whatwg.org/#dom-context-2d-getimagedata — returns ImageData with Uint8ClampedArray of (R, G, B, A) bytes per pixel; each of the 4 preset functions iterates this array in stride-4 applying its hardcoded per-channel arithmetic.
  • WHATWG (live). HTML Living Standard — Canvas 2D Context: putImageData(). html.spec.whatwg.org/#dom-context-2d-putimagedata — writes the modified Uint8ClampedArray back to the canvas after the preset transform.
  • WHATWG (live). HTML Living Standard — CSS filter property (NOT used by this tool). html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-filter + drafts.fxtf.org/filter-effects-1 — the CSS `filter` property composes blur / brightness / contrast / hue-rotate / sepia / saturate / invert / drop-shadow / grayscale primitives at the render-layer compositing stage. This tool does NOT use CSS filter — it applies 4 hardcoded RGB curves to the pixel buffer at export time via Canvas ImageData.
  • WHATWG (live). HTML Living Standard — HTMLImageElement (browser-native raster decoding). html.spec.whatwg.org/#htmlimageelement — universal browser entry point.
  • WHATWG (live). HTML Living Standard — HTMLCanvasElement.toBlob(). html.spec.whatwg.org/#dom-canvas-toblob — re-encodes canvas pixel buffer to Blob.
  • 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; Annex K quantisation tables.
  • W3C (PNG Working Group) (2003). Portable Network Graphics (PNG) Specification (Second Edition). W3C Recommendation 10 November 2003 / ISO/IEC 15948:2004 — PNG 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.

Sponsored

By ·