
10 Image Export Settings You're Probably Getting Wrong
The export settings that quietly ruin web images - quality at maximum, wrong colour space, chroma subsampling on graphics, baseline JPEG, the 300 DPI myth, interlacing, missing output sharpening - and the correct value for each.
Export dialogs are full of settings that default to whatever made sense for print in 2003. Most of them are never touched, and several of them cost real quality or real bytes on every image that leaves a design tool.
These ten come up in almost every asset handoff. For each one: what the setting does, what goes wrong, and the value you should use for web.
The Correct Defaults, In One Table
| Setting | Web value | Common wrong value |
|---|---|---|
| Quality | 80–85 JPEG, 75–82 WebP | 100 / Maximum |
| Colour space | sRGB | Adobe RGB, ProPhoto RGB |
| Colour profile | Embed sRGB, or convert and strip | Untagged wide-gamut |
| Chroma subsampling | 4:2:0 photos, 4:4:4 graphics | 4:2:0 everywhere |
| JPEG scan type | Progressive | Baseline |
| Resolution (DPI) | Irrelevant, ignore it | “300 for quality” |
| Metadata | None, keep orientation | All |
| PNG interlacing | Off | On |
| Resampling + sharpening | Bicubic Sharper, then output sharpen | Default, no sharpening |
| Bit depth and alpha | 8-bit, no alpha unless needed | 16-bit, alpha always on |
1. The Quality Slider at Maximum
Quality 100 is not “no loss”. In JPEG it means the quantization tables barely quantize, so you store enormous amounts of detail the eye cannot resolve. The file is two to three times larger than quality 85, and nobody can tell them apart.
| Setting | Size | Visible difference at display size |
|---|---|---|
| 100 | 640 KB | Baseline |
| 95 | 380 KB | None |
| 90 | 265 KB | None |
| 85 | 195 KB | None |
| 80 | 158 KB | None on most photographs |
| 70 | 118 KB | Slight on smooth gradients |
Measured on a 1600×1067 landscape photograph.
Photoshop’s Scale Is Not Everyone’s Scale
Photoshop’s “Save for Web” quality 0–100 does not map to libjpeg’s 0–100. Neither does Lightroom’s. The numbers below are the ones that matter, because they are what the encoder receives:
| Tool | Setting to use | Notes |
|---|---|---|
| Photoshop Export As | Quality 70–80 | Roughly libjpeg 85–90 |
| Photoshop Save for Web | Quality 60–70 | Legacy scale, more aggressive |
| Lightroom Export | Quality 76–82 | Above 77 switches to 4:4:4, so files jump |
| Figma | JPEG is not offered; export PNG and convert | Use Sharp or Squoosh afterwards |
| Affinity Photo | Quality 80–85 | Close to libjpeg |
| Sharp / cwebp / avifenc | See the table above | The authoritative scale |
That Lightroom detail is worth knowing: at quality 77 and above Lightroom disables chroma subsampling, so the file size jumps sharply for a change nobody sees on a photograph. Exporting at 76 rather than 80 often saves 30% with no visible difference.
AVIF Numbers Are Not JPEG Numbers
AVIF quality 58 is roughly JPEG quality 85. Copying your JPEG number into an AVIF encoder produces a file that is either enormous or mushy. Establish the value once per format in Squoosh, then apply it in your pipeline.
2. Exporting in a Wide-Gamut Colour Space
Your camera shoots Adobe RGB. Your editing document is ProPhoto RGB. You export straight to JPEG. On screen the result looks flat, desaturated, or slightly shifted, and nobody can work out why.
What Goes Wrong
A colour space defines what the numbers mean. R=200 in ProPhoto RGB is a different colour from R=200 in sRGB. If a browser gets ProPhoto numbers and treats them as sRGB, which it does when no profile is attached, every colour is wrong.
| Colour space | Gamut | Use for |
|---|---|---|
| sRGB | Smallest | The web. Always. |
| Display P3 | Wider | Modern displays, with an sRGB fallback |
| Adobe RGB | Wider, print-oriented | Print production |
| ProPhoto RGB | Enormous | Editing masters only |
The Fix
Convert to sRGB at export, do not merely assign it. Converting remaps the numbers; assigning just relabels them and produces wrong colours.
# ImageMagick: convert, not assign
magick master.tif -profile sRGB.icc -quality 85 web.jpg
# Sharp
sharp('master.tif')
.toColorspace('srgb')
.jpeg({ quality: 85 })
.toFile('web.jpg');
In Photoshop, use Edit → Convert to Profile → sRGB IEC61966-2.1, not Assign Profile. In Lightroom, set the export Colour Space to sRGB.
Display P3 Is the Exception
If you are deliberately targeting wide-gamut displays, P3 is valid, but it needs the profile embedded and an sRGB fallback for everything else. See the colour spaces guide.
3. Getting the Embedded Profile Backwards
This is the most confusing pair of settings in any export dialog, because both “embed” and “strip” can be right or wrong depending on what came before.
| Image state | Embed profile? | Result |
|---|---|---|
| Converted to sRGB | Optional | Correct either way; browsers assume sRGB |
| Still in Adobe RGB | Yes, required | Without it, colours render wrong |
| Still in ProPhoto | Yes, required | Without it, colours render badly wrong |
| Display P3 | Yes, required | Without it, oversaturated on P3 screens |
The Rule
Strip the profile only after converting to sRGB. Stripping a profile from a wide-gamut image is the single fastest way to break colour.
# Correct: convert first, then strip
magick master.tif -profile sRGB.icc -strip web.jpg
# Wrong: strips the profile that was explaining the numbers
magick master.tif -strip web.jpg
An sRGB profile costs 400 bytes to 4 KB depending on the variant. On a large catalogue that adds up, which is why converting and stripping is the efficient choice, but only in that order.
4. Chroma Subsampling Left on Default for Graphics
JPEG and lossy WebP store colour at half resolution by default, because human vision resolves brightness far more finely than colour. On photographs this is free bytes. On text, logos, and sharp colour edges it produces visible fringing.
| Mode | Colour resolution | Size | Right for |
|---|---|---|---|
| 4:4:4 | Full | Baseline | Screenshots, text, logos, saturated product shots |
| 4:2:2 | Half horizontal | −10% | Mixed content |
| 4:2:0 | Half both axes | −15–20% | Photographs |
How to Recognise the Symptom
Red or blue text on a white background develops a soft coloured halo. A crisp logo edge turns fuzzy on one side. Once you have seen it you cannot unsee it.
The Fix
# Force 4:4:4 for a screenshot or diagram
magick screenshot.png -sampling-factor 1x1 -quality 90 screenshot.jpg
# Photographs: 4:2:0 is correct and usually the default
magick photo.tif -sampling-factor 2x2 -quality 85 photo.jpg
# AVIF
avifenc --yuv 444 diagram.png diagram.avif
avifenc --yuv 420 photo.png photo.avif
// Sharp
sharp('screenshot.png').jpeg({ quality: 90, chromaSubsampling: '4:4:4' }).toFile('out.jpg');
sharp('photo.tif').jpeg({ quality: 85, chromaSubsampling: '4:2:0' }).toFile('out.jpg');
Lossy WebP always uses 4:2:0 with no option to change it. For graphics with text, use lossless or near-lossless WebP instead:
cwebp -near_lossless 60 diagram.png -o diagram.webp
5. Baseline Instead of Progressive JPEG
A baseline JPEG paints top to bottom, one band at a time. A progressive JPEG paints a full-frame low-quality pass first, then refines it in successive passes.
Why Progressive Wins
| Baseline | Progressive | |
|---|---|---|
| Perceived load | Reveals slowly from the top | Whole image appears, then sharpens |
| File size above ~10 KB | Baseline | Usually 2–8% smaller |
| File size below ~10 KB | Smaller | Slightly larger |
| Decode cost | Lower | Slightly higher |
| Support | Universal | Universal |
For anything above roughly 10 KB, progressive is smaller and feels faster. There is no reason to leave it off.
magick photo.jpg -interlace Plane -quality 85 photo-progressive.jpg
cjpeg -quality 85 -progressive -optimize -outfile out.jpg in.ppm
jpegtran -copy none -optimize -progressive -outfile out.jpg in.jpg
sharp('photo.tif').jpeg({ quality: 85, progressive: true, mozjpeg: true }).toFile('out.jpg');
In Photoshop’s Save for Web dialog it is the Progressive checkbox. In Export As it is not exposed, which is one reason to run exported files through an optimizer afterwards.
6. Chasing DPI
“Export at 300 DPI so it looks sharp on the web.” This belief is durable and completely wrong.
What DPI Actually Is
DPI, or more correctly PPI, is a number stored in the file’s metadata that tells a printer how large to print the image. Browsers ignore it entirely. A 1200×800 image is 1200×800 pixels whether the metadata says 72, 300, or 3000.
# These two files display identically in every browser
magick in.jpg -density 72 out-72.jpg
magick in.jpg -density 300 out-300.jpg
What Actually Controls Sharpness on Screen
Pixel dimensions, relative to the CSS size and the device pixel ratio.
| Displayed CSS width | 1× device | 2× device | 3× device |
|---|---|---|---|
| 400 px | 400 px | 800 px | 1200 px |
| 600 px | 600 px | 1200 px | 1800 px |
| 800 px | 800 px | 1600 px | 2400 px |
Cap at 2×. The visible improvement from 2× to 3× is very small, and the file is more than twice as large again. Serve the right pixel dimensions with srcset and the DPI field never matters. The retina and HiDPI guide covers the density rules.
7. Metadata Set to “All”
Most export dialogs default to including everything: EXIF, camera settings, GPS coordinates, editing history, an embedded thumbnail, and copyright fields.
| Metadata | Size | Keep for web? |
|---|---|---|
| EXIF camera data | 2–10 KB | No |
| GPS coordinates | Under 1 KB | Never |
| Embedded thumbnail | 10–60 KB | No |
| Editing history (XMP) | 5–40 KB | No |
| ICC profile | 0.4–4 KB | Only if not sRGB |
| Orientation | Bytes | Apply it, then drop it |
| Copyright / IPTC | Under 1 KB | Your call |
The Fix
In Photoshop Export As, set Metadata to None or Copyright and Contact Info. In Lightroom, set it to Copyright Only. Then verify:
# What is actually in the file?
exiftool photo.jpg
# Check specifically for location data
exiftool -gps:all photo.jpg
# Strip everything, restore orientation
exiftool -all= -tagsFromFile @ -Orientation -overwrite_original photo.jpg
GPS coordinates deserve special mention. A photograph taken at home and published on a public site tells everyone where you live. If your site accepts uploads, stripping location data is a safety measure. The metadata and privacy guide covers this fully.
8. PNG Interlacing Left On
Adam7 interlacing makes a PNG render as a progressively refining mosaic instead of top to bottom. It sounds like the PNG equivalent of progressive JPEG. It is not.
Why It Is Different
| Progressive JPEG | Interlaced PNG | |
|---|---|---|
| File size effect | 2–8% smaller | 20–35% larger |
| Decode cost | Slightly higher | Substantially higher |
| Worth using | Yes | No |
Adam7 breaks the image into seven passes, which destroys the row-to-row coherence that PNG’s filters rely on. The compression gets meaningfully worse.
Turn it off. In Photoshop it is the Interlaced checkbox. In pngquant and oxipng it is off by default. If you have inherited interlaced PNGs:
# Remove interlacing and optimize
magick in.png -interlace none out.png
oxipng -o 4 --strip safe out.png
9. No Output Sharpening After Downscaling
Every downscale softens an image. Resampling averages neighbouring pixels, so fine detail and edge contrast are reduced. This is physics, not a tool defect, and it is why a 4000 px photo scaled to 800 px looks slightly mushy compared to a photo shot at 800 px.
The Fix: Two Settings, Not One
Choose the right resampling filter.
| Filter | Best for |
|---|---|
| Bicubic Sharper (Photoshop) | Reduction. Use this. |
| Bicubic Smoother | Enlargement only |
| Lanczos | Reduction, in most CLI tools |
| Mitchell | Reduction, gentler than Lanczos |
| Nearest neighbour | Pixel art only |
Then sharpen for output. A light unsharp mask restores the edge contrast the resample removed:
# ImageMagick: resize with Lanczos, then a light unsharp mask
magick in.jpg -filter Lanczos -resize 800x800 -unsharp 0x0.75+0.75+0.008 -quality 85 out.jpg
// Sharp: sigma, flat, jagged
sharp('in.jpg')
.resize({ width: 800, kernel: 'lanczos3' })
.sharpen({ sigma: 0.7, m1: 0.6, m2: 2 })
.jpeg({ quality: 85 })
.toFile('out.jpg');
Do Not Overdo It
Over-sharpening produces bright halos along high-contrast edges, and those halos compress badly, so the file grows as well as looking worse. Sharpen lightly, view at 100%, and stop as soon as you can see the effect.
Sharpen Last
The order is: resize → sharpen → encode. Sharpening before resizing amplifies detail that the resize then throws away.
10. Wrong Bit Depth and Unnecessary Alpha
Two settings that quietly double file size.
16-Bit Exports
Editing in 16-bit is correct: it prevents banding as you push tones around. Exporting in 16-bit is not, because no browser benefits and the file is twice the size.
# Convert a 16-bit PNG to 8-bit
magick in-16bit.png -depth 8 out-8bit.png
The exception is AVIF, which supports 10-bit and uses it well for HDR and smooth gradients. That is a deliberate choice for a specific reason, not a default. See the HDR guide.
Alpha Channels Nobody Needs
A PNG-32 with a fully opaque alpha channel still stores that channel. For a photograph with no transparency, dropping it and switching to a lossy format saves a great deal:
# Flatten transparency onto white and switch format
magick in.png -background white -alpha remove -alpha off -quality 85 out.jpg
PNG-24 Where PNG-8 Would Do
An illustration with a limited palette does not need 16.7 million colours:
# 256-colour palette, typically 60-70% smaller on flat art
pngquant --quality 65-90 --speed 1 illustration.png
oxipng -o 4 --strip safe illustration-fs8.png
Use pngquant on illustrations, icons, and flat graphics. Do not use it on photographs or screenshots with gradients, where 256 colours produce visible banding. The PNG guide covers the palette decision.
Export Presets Worth Saving
Rather than remembering ten settings, save a preset per content type.
Photograph for Web
| Setting | Value |
|---|---|
| Format | JPEG (plus WebP and AVIF derivatives) |
| Quality | 82 |
| Colour space | sRGB, converted |
| Profile | Strip after conversion |
| Subsampling | 4:2:0 |
| Scan | Progressive |
| Metadata | None |
| Resample | Lanczos or Bicubic Sharper |
| Sharpening | Light unsharp mask |
| Bit depth | 8-bit, no alpha |
Screenshot or UI Capture
| Setting | Value |
|---|---|
| Format | PNG, plus lossless WebP |
| Quality | Lossless |
| Colour space | sRGB |
| Subsampling | 4:4:4 if JPEG is unavoidable |
| Interlacing | Off |
| Metadata | None |
| Resample | Avoid resizing at all; capture at final size |
| Bit depth | 8-bit |
Illustration or Icon
| Setting | Value |
|---|---|
| Format | SVG if drawn, otherwise PNG-8 |
| SVG optimization | SVGO with removeViewBox disabled |
| Palette | pngquant --quality 65-90 |
| Interlacing | Off |
| Metadata | None |
Automate It Instead
The most reliable way to get all ten right is to stop making them by hand. Export one high-quality master, then derive everything programmatically:
import sharp from 'sharp';
const WIDTHS = [400, 800, 1200, 1600];
async function derive(master, basename) {
const jobs = [];
for (const width of WIDTHS) {
const base = sharp(master)
.rotate() // orientation applied, tag dropped
.resize({ width, kernel: 'lanczos3', withoutEnlargement: true })
.sharpen({ sigma: 0.7, m1: 0.6, m2: 2 }) // output sharpening
.toColorspace('srgb'); // converted, not assigned
jobs.push(
base.clone().avif({ quality: 58, chromaSubsampling: '4:2:0' }).toFile(`${basename}-${width}.avif`),
base.clone().webp({ quality: 80, effort: 6 }).toFile(`${basename}-${width}.webp`),
base.clone().jpeg({ quality: 82, progressive: true, mozjpeg: true, chromaSubsampling: '4:2:0' })
.toFile(`${basename}-${width}.jpg`)
);
}
return Promise.all(jobs);
}
Or remove the export step entirely and let an image CDN derive everything from the master on request. Sirv applies width, format, and quality from URL parameters, so the ten settings are decided once in configuration rather than in every export dialog.
Summary
The Ten Corrections
| # | Setting | Change it to |
|---|---|---|
| 1 | Quality | 80–85 JPEG, 75–82 WebP, 55–63 AVIF |
| 2 | Colour space | Convert to sRGB |
| 3 | Profile | Embed if wide-gamut, strip only after converting |
| 4 | Subsampling | 4:2:0 photos, 4:4:4 graphics |
| 5 | Scan type | Progressive |
| 6 | DPI | Ignore it, control pixel dimensions |
| 7 | Metadata | None, plus orientation applied |
| 8 | PNG interlacing | Off |
| 9 | Resample and sharpen | Lanczos, then light output sharpening |
| 10 | Bit depth and alpha | 8-bit, alpha only when needed |
Checklist
- ✅ Quality is set per format, using each encoder’s own scale
- ✅ Every export is converted to sRGB, not assigned it
- ✅ Profiles are stripped only after conversion
- ✅ Graphics and screenshots use 4:4:4 or lossless
- ✅ Every JPEG above 10 KB is progressive
- ✅ Nobody on the team is still exporting “at 300 DPI”
- ✅ Metadata is set to None, with orientation baked in
- ✅ No PNG is interlaced
- ✅ Downscaled images get a light output sharpen, applied after the resize
- ✅ No 16-bit files and no unused alpha channels reach production
Settings 1, 2, and 7 fix themselves the moment you move derivation into a script. That is the real recommendation: get the master right, then let a pipeline make every other decision consistently.