ScreenshotNeo

BlogHow-to

How to compress website thumbnails without making text unreadable

Keep thumbnail files small without sacrificing legibility: size for the display, compare formats and encodes, and move text into HTML when possible.

By the ScreenshotNeo team4 October 20269 min read

To compress website thumbnails without making text unreadable, first keep text out of the image when you can: render titles and labels as HTML using web fonts. When text must be part of the bitmap, size the image for its actual display slot, compare formats and quality levels, and inspect the smallest lettering at the size readers will see. There is no universally safe quality setting; choose the smallest file that passes visual review.

This guide covers the image workflow and includes runnable commands for inspecting and converting a thumbnail with ImageMagick. For website screenshots, it also shows how to capture a consistent source image before optimizing it.

1. Decide whether the text belongs in the image

Text baked into an image cannot be selected or searched like page text, and it does not resize with the page’s typography. Google Chrome’s web.dev format guide advises reconsidering text in image assets and using web fonts instead. Keep the thumbnail artwork in the image, then layer its title or label in HTML where possible. web.dev: Image performance

If text must remain baked in—for example, because the image itself is the deliverable—treat its thinnest strokes and smallest characters as the limiting detail. Lossy compression can soften sharp edges and create artifacts around high-contrast colored text on flat backgrounds. Review the actual result rather than relying on a nominal quality number. web.dev: Image performance

2. Start with the rendered size

Find the thumbnail’s CSS display dimensions and the range of screens where it appears. Generate a candidate appropriate to that slot and expected display density instead of shipping a needlessly large original and asking every browser to shrink it. For responsive layouts, provide a proportionate set of image candidates and verify which one the browser downloads.

More variants can reduce bytes for particular slots, but each one adds markup, generated assets, and cache entries. Keep only variants that serve real display contexts.

3. Compare formats and compression settings

Image content What to compare Review closely for
Photograph or detailed artwork JPEG, lossy WebP, and lossy AVIF where supported Smearing, blocking, and loss of fine detail
Text, line art, flat color, or sharp edges Lossy and lossless candidates; include PNG or lossless WebP when useful Soft letter strokes, ringing, halos, and color bleeding
Transparency required Formats and encoders that preserve alpha, with the needed browser fallback Fringes around transparent edges and background color changes

WebP supports lossy and lossless compression and is widely supported in modern browsers; AVIF also has lossy and lossless modes, though its browser support is less broad. Use a fallback if your site’s browser support requires one. There is no universal quality number: test the image and encoder you will actually ship. web.dev: Image performance

4. A repeatable local workflow

  1. Keep an untouched source image.
  2. Create candidates at the intended pixel dimensions, including any density variant the layout needs.
  3. Encode several quality levels for the relevant format, and include a lossless candidate for text-heavy or graphic artwork when its size is acceptable.
  4. Open each candidate at the actual on-page display size. Then zoom in on the smallest text and sharp edges to inspect artifacts.
  5. Record format, dimensions, file size, and encoder settings for the selected candidate so the choice can be reproduced.

The following examples use ImageMagick’s magick command. They resize to a 640-pixel-wide candidate while preserving aspect ratio. Replace the paths and dimensions with those for your layout. The quality values below are trial points, not universal recommendations. Confirm the commands and encoder options against the ImageMagick version installed on your system.

JPEG candidates

magick source.png -resize 640x -strip -quality 82 thumbnail-q82.jpg
magick source.png -resize 640x -strip -quality 72 thumbnail-q72.jpg
magick identify -format '%f %wx%h %b\n' thumbnail-q82.jpg thumbnail-q72.jpg

WebP candidates

magick source.png -resize 640x -strip -quality 82 thumbnail-q82.webp
magick source.png -resize 640x -strip -quality 72 thumbnail-q72.webp
magick identify -format '%f %wx%h %b\n' thumbnail-q82.webp thumbnail-q72.webp

For a lossless WebP comparison, if the installed ImageMagick build supports it:

magick source.png -resize 640x -strip -define webp:lossless=true thumbnail-lossless.webp

Encoder support and options vary by build. If a command fails or a format is unavailable, check magick -version and the encoder delegates included in that build. A graphical comparison tool such as Squoosh can also help compare outputs visually. web.dev discusses image optimization tools

5. Deliver responsive formats with a deliberate fallback

Use <picture> when you want to offer modern formats and retain a fallback. The browser selects the first supported source; the img element supplies the fallback and accessible alternative text.

<picture>
  <source type="image/avif" srcset="/images/thumb-640.avif">
  <source type="image/webp" srcset="/images/thumb-640.webp">
  <img src="/images/thumb-640.jpg"
       width="640" height="360"
       alt="A concise description of the thumbnail's meaningful content">
</picture>

For responsive candidates, add appropriately sized srcset entries and a sizes value that reflects the layout. Avoid producing variants that are not used. If a server selects the representation based on the request’s Accept header, send an appropriate Vary: Accept response header so caches distinguish the representations. web.dev: Image performance

6. Make the content accessible

Use HTML text for words that can be rendered separately. Give informative thumbnails an appropriate text alternative. If an image contains complex information such as a graph or diagram, provide a complete text equivalent of the information; a brief alt description alone may not carry all of its detail. W3C WAI Images Tutorial

7. Capture consistent website thumbnails

If your thumbnail is a screenshot of a web page, capture the same page state and viewport each time before comparing compression. Browser rendering, viewport dimensions, and page loading can change the pixels, making an image comparison misleading. A local browser automation workflow can produce the source image; the exact setup depends on your existing browser tooling.

ScreenshotNeo is a website screenshot API and MCP server. It can return a screenshot in PNG, JPEG, or WebP from one GET request. Its options include viewport and device presets, full-page capture with lazy images loaded, waiting for a selector or network idle, custom CSS and JavaScript, and element capture by CSS selector. See the ScreenshotNeo API documentation.

cURL

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)

Node.js

const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://stripe.com'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', res);

The Node.js example uses Bun’s file-writing helper. In Node.js, save the response body with await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()))) after the status check.

These examples show the basic request. The API supports additional parameters for output format, dimensions, device presets, full-page or element capture, waits, custom CSS, and other capture settings. Use the docs for parameter names and combinations. Keep the output format and capture settings constant while comparing compression candidates.

Or skip the browser setup

One ScreenshotNeo request can capture a source image:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the API documentation for output and capture options. ScreenshotNeo accepts cookie and consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers indicate the page verdict and billing status. Its MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 shots.

Sign up for 1,000 free screenshots a month, with no card required.

Troubleshooting

Symptom Likely cause What to do
Small text looks smeared Lossy compression or an oversized resize reduction damaged thin strokes. Compare a higher quality candidate, a lossless option, or move the text into HTML. Inspect at display size and zoom.
Colored letters have fuzzy edges Lossy chroma subsampling can affect high-contrast colored text on flat backgrounds. Try lossless encoding or separate the text from the image. Review the actual colors and background.
Image looks sharp locally but blurry on a high-density screen The delivered candidate has too few pixels for the rendered slot and display density. Provide a larger responsive candidate for that context, then verify the browser selects it.
AVIF or WebP does not display for some visitors The client or delivery path does not support that representation. Provide a fallback with <picture>, or verify server content negotiation and cache behavior.
Visitors receive the wrong format from cache A cache may reuse a response selected for a different Accept header. When the server varies output by Accept, use Vary: Accept and check the cache configuration.
The image is larger than expected Dimensions may be oversized, the content may not compress well, or the chosen mode may be lossless. Check the pixel dimensions and compare suitable lossy and lossless formats. Do not sacrifice text legibility just to hit a size target.
ImageMagick reports an unsupported format or option The installed build may lack that encoder or use different option support. Check magick -version and available delegates, then use a supported encoder or another image optimization tool.
A screenshot changes between runs The page state, viewport, loaded images, or timing may differ. Fix the viewport and wait condition, and capture only after the intended page content is ready.

Performance, reliability, and cost considerations

  • Performance: Deliver the dimensions the layout needs and use responsive candidates where they save meaningful bytes. Modern formats can help, but the content and encoder affect the result. Confirm with the actual image and target browsers.
  • Reliability: Keep the original asset and a record of selected settings. For screenshot sources, keep viewport and page readiness conditions consistent. Use format fallbacks and correct cache variation when serving negotiated formats.
  • Operational cost: Every responsive size and format increases storage, generation work, markup, and cache entries. Generate only useful variants. Automated image services can simplify optimization, but their cost may not suit every workflow; compare against local tools such as Squoosh or ImageOptim.
  • ScreenshotNeo pricing: Free includes 1,000 shots per month; paid plans are Starter $5 for 3,000, Growth $15 for 15,000, Pro $39 for 60,000, Scale $99 for 250,000, and Business $249 for 1,000,000. Yearly billing gives two months free, and every feature is on every plan. Only clean shots are billed; inspect the response’s verdict and billing headers.

FAQ

What image format keeps text sharp?

There is no single winner for every image. Compare a lossless candidate for text-heavy graphics with suitable lossy candidates, and judge the lettering at its intended display size. HTML text is preferable when the wording can be separate.

How do I reduce image file size without blurring small text?

Start with appropriate pixel dimensions, then compare formats and encodes. If the text is still unreadable, move it into HTML or use an encoding that preserves the relevant edges rather than continuing to lower quality.

Should text be part of a thumbnail image?

Usually, titles and labels are better as HTML text: they remain selectable, searchable, and responsive to typography settings. Keep text in the bitmap only when the image itself needs to carry it.

Should every thumbnail have multiple format and size variants?

No. Add variants for real browser support and layout needs, then weigh byte savings against extra assets, markup, and cache entries.