Duotone & Gradient Map Generator
Duotones and gradient maps from your photo — and the same effect as a CSS filter.
Preview
Colours
Presets
Presets
Adjust
Download
Full size of your photo; PNG keeps transparency.
Use it in CSS
The same effect as an SVG filter: paste the <svg> once in your page, then add the class to any image, video or element. The picture file stays as it is.
SVG filter (HTML)
CSS
About the Duotone & Gradient Map Generator
A duotone recolours a photo with two colours: the shadows take one colour, the highlights the other, and every tone in between a mix of the two — the bold look of music posters, magazine covers and brand campaigns. A gradient map does the same with up to eight colours along a ramp, for tritones, heat-map looks or sunset tones. Start from one of the presets or pick your own colours, adjust contrast, brightness and intensity, and see the result at once on your photo (or on the sample picture before you choose one).
Download the picture as PNG, JPG or WebP at full size — transparent areas stay transparent in PNG and WebP — or copy the matching SVG filter to get the same effect in CSS with filter: url(#…), on any image, video or element of a web page, without making new image files. Everything runs in your browser; the photo is never uploaded.
How to use it
- Choose a photo, drop it on the page or paste it with Ctrl+V (⌘V on a Mac). Until you do, the sample picture shows the effect.
- Pick Duotone for two colours or Gradient map for up to eight, then a preset — or set the colours yourself: the shadow colour is the left end of the ramp and the highlight colour the right end. Swap (or Reverse for a gradient map) turns the ramp round.
- For a gradient map, add colour stops and set each one’s position from 0 to 100 % and its colour.
- Fine-tune with Contrast, Brightness and Intensity (below 100 % the original colours show through). Press Show original to compare.
- Download the picture in the format you need, or copy the SVG filter and the CSS under Use it in CSS.
Examples
#808080 · shadows #0b1d51 · highlights #f2c14e
#7f6f4f
The luma of 128 is 128 ÷ 255 = 0.502, so each channel goes 50.2 % of the way from the shadow colour to the highlight colour: red 11 + 0.502 × (242 − 11) = 127, green 29 + 0.502 × (193 − 29) = 111, blue 81 + 0.502 × (78 − 81) = 79.
Navy & gold · contrast 0 · brightness 0 · intensity 100 %
<filter id="duotone-0b1d51-f2c14e" color-interpolation-filters="sRGB">
<feColorMatrix type="matrix" values="0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0 0 0 1 0"/>
<feComponentTransfer>
<feFuncR type="table" tableValues="0.0431 0.949"/>
<feFuncG type="table" tableValues="0.1137 0.7569"/>
<feFuncB type="table" tableValues="0.3176 0.3059"/>
</feComponentTransfer>
</filter>Each table runs from the shadow colour (11 ÷ 255 = 0.0431 for red) to the highlight colour (242 ÷ 255 = 0.949).
Stops #1d1d1b at 0 %, #c2462e at 50 %, #f4ecd8 at 100 %
Near-black shadows, brick-red mid-tones and cream highlights
The stops sit on whole multiples of 50 %, so each channel’s table needs only three values.
Any preset · intensity 60 %
Each pixel is 60 % effect and 40 % original colour
Common uses
- Giving a set of photos for a website, deck or social posts one consistent brand colour treatment.
- Poster, album-cover and event artwork in the two-colour style.
- Recolouring images on a web page with a CSS filter, so hover states and themes can change them without new files.
- Gradient-map looks such as heat maps, sepia, blueprints or sunset tones for backgrounds and banners.
How the colours are mapped
- Luma: each pixel’s brightness is worked out from its red, green and blue values with the weights of ITU-R BT.709: Y′ = 0.2126 R′ + 0.7152 G′ + 0.0722 B′. Green counts most because the eye is most sensitive to it.
- Contrast and brightness stretch the luma around mid-grey and shift it: Y″ = s·Y′ + 0.5 − 0.5·s + b, where s runs from 0 to 2 (contrast −100 to +100) and b from −0.5 to +0.5 (brightness −100 to +100). The result is kept between 0 and 1.
- The ramp: Y″ = 0 gets the first colour (the shadows), 1 the last colour (the highlights), and values in between are mixed linearly between the two nearest stops. Below the first stop and above the last one the end colour holds.
- Intensity mixes the result with the original pixel: result = i × effect + (1 − i) × original.
- Transparency is never changed: the alpha channel passes through as it is.
Using the SVG filter in CSS
The copied markup is an <svg> holding one <filter>: an feColorMatrix whose rows turn every pixel into its adjusted luma, then an feComponentTransfer with one table per colour channel that holds the ramp — a table interpolates linearly between evenly spaced values, so the tool spaces them to land exactly on your stops. Below 100 % intensity an feComposite with operator="arithmetic" mixes the original back in.
Paste the <svg> once anywhere in the page’s HTML, then give any image, video or element the class from the CSS: .duotone { filter: url(#duotone-0b1d51-f2c14e); }. The id names the colours and any contrast, brightness or intensity change (duotone-0b1d51-f2c14e-i60 at 60 %), so several different filters can sit in one page — give each its own class. The filter carries color-interpolation-filters="sRGB" on purpose: without it, browsers run filters in linear RGB (its initial value) and the tones no longer match the preview. The image file itself stays unchanged, so the effect can be switched off on hover or in another theme.
Choosing colours
A duotone reads best when its two colours are far apart in lightness: a dark, fairly saturated shadow colour (navy, plum, forest green) and a light highlight colour (gold, peach, mint). Two colours of similar lightness flatten the picture into one tone. If the shadows come out light and the highlights dark, the ramp is the wrong way round — use Swap. For photos of people, warm highlight colours usually look more natural on skin than cold ones. With a gradient map, a middle stop sets the colour of the mid-tones, where most of a photo’s detail is.
Limitations
- Colours are worked out on the sRGB values your browser decodes; photos in wider colour spaces such as Display P3 are converted to sRGB first, and the download is an sRGB picture.
- Pictures larger than about 40 megapixels are scaled down for the download so that browsers can process them.
- JPG has no transparency: transparent areas are filled with white in a JPG download (PNG and WebP keep them).
- Only the first frame of an animated GIF or WebP is used.
- HEIC photos open natively in Safari; other browsers first download a decoder from this site (1.4 MB, once).
Privacy
Everything happens in your browser. What you enter or open here is not uploaded or stored by MySmartCoPilot.
Frequently asked questions
What is a duotone effect?
A duotone shows a picture in two colours only: one for the dark tones, one for the light tones, and mixes of the two in between. It keeps all the detail of a black-and-white photo but replaces black and white with colours of your choice.
What is the difference between a duotone and a gradient map?
A duotone is a gradient map with two colours. A gradient map can have more colour stops along the ramp, so the mid-tones can get a colour of their own — three stops make a tritone.
Will the CSS filter look exactly like the download?
It uses the same calculation: the same luma weights, the same contrast and brightness and the same colour table. Only rounding differs: in our tests with Chromium, Firefox and WebKit, no pixel of the filtered picture differed from the download by more than 3 of 255 levels — far too little to see.
Does it keep transparency?
Yes. The alpha channel is never changed, so PNG and WebP downloads keep transparent and semi-transparent areas — logos and cut-out photos stay cut out. JPG cannot store transparency, so those areas become white.
Can I use the effect on a video or a background image?
Yes, with the CSS filter: filter: url(#…) works on <img>, <video>, <canvas> and any other element, including one with a CSS background image. The download, in contrast, is a still picture.
Is my photo uploaded?
No. The photo is opened, recoloured and saved in your browser; nothing is sent anywhere, and the page keeps working offline once it has loaded.