Shrink an image to fit Discord
Drop an image — or several at once — pick your tier, and smallcord re-encodes them in your browser to land under the limit.
Image shrinker
Everything runs in your browser — your files never leave your device.
How it works
Pick your tier — or type a target
10 MB (free), 50 MB (Nitro Basic), or 500 MB (Nitro) — or choose Custom and type any KB/MB target, like 8 MB to leave headroom.
Drop an image
Your browser reads it locally, then re-draws it to a canvas and re-encodes it. No upload happens.
Download the smaller file
smallcord lowers quality first, then dimensions if needed, and shows the real before/after size.
What actually happens to your image
smallcord draws your image onto an off-screen <canvas> and re-encodes it with the browser's
built-in JPEG/WebP encoder at a lower quality — and, if quality alone can't get under your limit, at reduced
dimensions too. That is Auto (smallest), the default. Switch Output format to Lossless (PNG)
and the same canvas writes a PNG instead: no quality is thrown away, and the fit is found by spending a
colour budget first — 256, then 128, 64, 32, 16 palette entries, all at full size — with resolution
dropped only if the smallest permitted palette still misses your limit. It plans a starting quality from the pixel count, then re-encodes and measures the real bytes,
stepping quality (and finally size) down until the file fits or hits a sensible floor. Because the encoder's output
depends on the picture itself, the numbers you see are the true output size, not a guess.
Honest limits: photos and screenshots shrink a lot, since JPEG/WebP thrive on smooth tone and gradients. A crisp PNG of line art, a QR code, or pixel art can look worse as JPEG and may barely shrink — the artifacts land exactly on the hard edges that carry the meaning. That is what the Output format control is for: set it to Lossless (PNG) and every pixel comes back exactly as it went in. Two levers exist there: fewer pixels, and — since your browser's canvas can only write three colour bytes per pixel — fewer colours. The PNG colours control writes a real indexed (colour-type-3) PNG: one palette entry per colour and one index per pixel, half a byte at 16 colours. Measured on smallcord's own 1344×768 social card, a flat brand-coloured graphic with text — the same file this page links as its social preview, so you can check these numbers against it yourself: the canvas truecolour PNG is 194.0 KB, the same pixels at 256 colours are 44.1 KB, at 64 colours 27.0 KB and at 16 colours 12.9 KB. Auto is the safe default: as long as your file fits, it writes the indexed file only when your image already uses 256 colours or fewer, so the result is exactly lossless — that card uses 29,004, so Auto leaves it truecolour, tells you what 256 colours would have weighed, and lets you decide. When the file does not fit, Spend colours before pixels takes over rather than letting the page quietly resize your line art: it ladders the palette down at full size, stops at the first size that fits, refuses photographs outright, and names the palette it spent on the result line. Note the honest ceiling in those numbers: the card actually ships as a 9.9 KB WebP, so even 16 colours of lossless PNG is bigger than the lossy file — which is exactly why Auto (smallest) is the default output format. Those figures now include a per-scanline filter search: the indexed file is built twice, once with PNG filter byte 0 on every row and once with the best of the five filter types picked row by row, and the smaller of the two is what you get — worth 1.4 KB of the 44.1 KB above, and nothing at all on the 16-colour version, which is why it is written as "never worse" rather than "always smaller". The catch that survives is still real and this page still states it: there is no zopfli and no second compression pass, so oxipng, pngquant and ImageOptim can still beat it on a file they have already optimised, and the verdict hands your original back rather than a worse file when that happens. In Auto (smallest) the re-encode is lossy: saving an already-compressed JPEG again always loses a little detail. Transparency depends on which encoder you end up with: the WebP path Auto uses in Chrome, Firefox, Edge and Safari keeps the alpha channel, Lossless (PNG) keeps it too, and only the JPEG fallback — used when your browser cannot encode WebP at all — has no alpha and flattens transparent pixels to white. If even the smallest usable version is still over your limit, smallcord tells you plainly — and names the long edge that would fit, with a one-click retry that resizes and re-encodes here, rather than pretending it fit.
Metadata does not survive re-encoding — verified, not assumed. A phone JPEG carries an EXIF block alongside the pixels: camera model, capture time, and — if location was on — the GPS coordinates of where the photo was taken. Because this page rebuilds the file from decoded pixels on a canvas, none of that block is copied: we checked the actual output bytes against a test image and found no EXIF container at all, so the file you download here carries no camera info, no timestamps, and no location. One EXIF field does matter visually — Orientation. Phones usually store portrait shots sideways plus a "rotate me" flag, and your browser applies that flag when it decodes the image, so the output comes out already upright with the flag no longer needed. Our test suite re-encodes a sideways-stored Orientation=6 fixture on every run; rotated or squashed output would fail it.
Custom targets have a floor. Quality can only take a file so far: below roughly quality 40, JPEG/WebP artifacts get ugly, and we never shrink below 20% of each side, because a thumbnail-sized "success" is useless. A 4000×3000 photo therefore bottoms out somewhere in the low hundreds of kilobytes — ask for a 50 KB custom target and smallcord will run the real encode, show you the measured size, and say plainly that the target is out of reach at those dimensions. The fix is fewer pixels, not a lower quality slider — which is what the Resize first — max long edge control does. Set it (or hit the one-click suggestion in the verdict: for that 4000×3000 photo at 50 KB the planner says a 567 px long edge, i.e. 567×425) and the resize and the re-encode happen in a single canvas draw, on your device, without leaving the page.
Worked examples, measured — not guessed
Where these numbers come from. Every byte figure below was produced on 28 July 2026 by driving this
exact page in headless Chromium 150 with tools/measure-image-encode.cjs from the smallcord
source tree: a real file goes into the same file input you use, and the number reported is the size of the
blob the page's own Download button hands back. Nothing here is copied from a vendor's marketing page.
Anything we could not measure is labelled a rule of thumb, in those words. Your own results will differ —
encoded size depends on the picture, and no two photos compress alike.
A 1280×2077 PNG screenshot (359.4 KB)
The source is a full-page screenshot of this very page — taken before these explainer sections were added, which is why it is only 2,077 pixels tall — saved by the browser as PNG: 1280×2077 pixels, 368,031 bytes. Screenshots are the single most common thing people drag into Discord, and they are the case where the numbers surprise people most, because a PNG of flat UI is already efficient.
| Target you pick | File you get | Output pixels | Quality used |
|---|---|---|---|
| Free, 10 MB | 233.2 KB WebP | 1280×2077 (untouched) | 92 |
| Custom, 200 KB | 53.4 KB WebP | 772×1252 | 42 |
| Custom, 40 KB | 14.0 KB WebP | 344×559 | 42 |
Read the first row carefully: against the free 10 MB limit the page did not resize anything and used its quality ceiling of 92, and the result was still 35% smaller than the PNG — that saving is the format change alone. Read the second row just as carefully, because it shows a real weakness. You asked for 200 KB and got 53.4 KB. The search only ever steps down from its opening plan, and that plan assumes photographic detail (roughly 1.2 bytes per pixel at full quality). Flat interface pixels beat that assumption by a wide margin, the very first rung already fit, and smallcord stopped there instead of climbing back toward your budget. So a tight custom target on a screenshot or on line art can hand you a file far smaller — and softer — than you actually needed. On the tier chips this never bites, because a photo-sized file under a 10 MB, 50 MB or 500 MB budget gets planned at or near the quality ceiling anyway.
A file that is already small: 1344×768 WebP, 9.9 KB
Dropping smallcord's own social-card image in at the free tier produced a 14.2 KB file — larger than the 9.9 KB original. Nothing went wrong. That card was exported once at a low quality by its author; this page re-encodes at quality 92 by default when there is budget to spare, and quality 92 costs more bytes than whatever the original was saved at. This is the honest shape of a re-encoder: it does not know how much compression your file has already had, it just runs the encoder again with the settings your budget allows. When the output comes out bigger, the result line now says so in those words — “% LARGER than your original — your original is already smaller, so keep it” — instead of the older, vaguer “about the same size”. Keep the original in that case; it already fits.
A 12-megapixel photo, 4000×3000
We do not have a phone photo we are free to publish measurements from, so this example is split into the
part we can state exactly and the part we can only estimate. What is exact is the plan: the page's
planner module (fit-image.js, the same code the browser runs) was called directly in Node for a
4000×3000 image and returned, at the free 10 MB budget, quality 0.85 at full resolution — every pixel
kept — and at both the 50 MB and 500 MB budgets its quality ceiling of 0.92, again at full
resolution. For a normal phone photo, in other words, the answer is “keep all the pixels, soften slightly”,
and on Nitro “barely touch it”.
What is measured but synthetic: to see 12 megapixels actually go through the encoder we built a 4000×3000 test image in the browser (an illustration upscaled to that size with per-pixel noise added so it would not compress unrealistically well) and saved it as a quality-90 JPEG of about 2.7 megabytes. At the free tier the page returned about 1.8 megabytes of WebP at full 4000×3000 and quality 85. At the Nitro tier it returned about 2.9 megabytes — bigger than the source, the same effect as the social card above. Treat those three figures as an illustration of the mechanism, not as what your camera roll will do: a synthetic image is not a photograph.
Rule of thumb, not a measurement: a 12-megapixel JPEG straight out of a phone is usually somewhere between 3 and 6 megabytes, which already fits the free 10 MB limit with room to spare. The people who genuinely need this page are usually carrying something else — a screenshot of a 4K monitor, a scan, a export from a design tool, or a burst of photos they want to send as one batch.
Why you get a .webp back
When the page loads it paints a 2×2 canvas and asks the browser to encode it as WebP. If the browser says yes — every current desktop and mobile browser does — Auto (smallest) re-encodes everything you drop to WebP. If it says no, Auto falls back to JPEG and tells you so in the download button. Auto never asks you to choose between those two, because there is nothing to choose: on the same source at the same quality, in the same browser, WebP won every comparison we measured.
The one real choice is lossy or not, and that is the Output format control above the drop zone. Auto is lossy and is the right answer for photographs and most screenshots. Lossless (PNG) throws nothing away, which matters for line art, pixel art, QR codes and UI captures — but it also means the quality lever does not exist, so a PNG gets smaller only by spending fewer pixels or fewer colours. The measurement two paragraphs down is the honest warning label for it: the canvas PNG encoder is a plain truecolour deflate writer, and on the 1280×2077 screenshot it produced 497.1 KB where WebP produced 233.2 KB. smallcord's indexed-palette pass closes a lot of that gap — on the 1344×768 social card measured above, 194.0 KB of truecolour becomes 44.1 KB at 256 colours — but it costs colour accuracy, so it only runs when it is lossless or when you pick a palette size yourself, and even at 16 colours that card is 12.9 KB against the 9.9 KB WebP it actually ships as. Against a PNG you already exported from a real optimiser, expect the page's PNG to still be the bigger of the two — and when it is, the verdict says so and gives you your original back.
Which lever gets spent, and on what. When a PNG misses your limit at full size, Spend colours
before pixels (ticked by default) makes the page try 256, then 128, 64, 32 and 16 palette entries at
full resolution before it will resize anything. Both roads are actually encoded and the smaller file wins,
so the result can never be bigger than the resize-only one — the verdict names which lever paid, in the
words “fitted at full size with 64 colours” or “downscaled to 61%”.
It helps screenshots, UI captures, pixel art, line art and flat illustration, because those are made
of a few hundred flat colours and a palette costs them almost nothing. Measured here (headless Chromium,
real encodes — rerun it with node test/color-budget-measure.cjs): on a 1280×800 UI capture with
461 distinct colours, the truecolour canvas PNG is 197,083 B, 256 colours is 61,350 B and 16 colours is
10,493 B, while the average pixel moves 0.02 → 0.42 of 255 in colour — invisible.
It hurts photographs, so it refuses them. On a 900×600 photograph the average pixel moves 14.6 at
256 colours and 40.4 at 16: that is banding you can see before the ladder has taken a real step. smallcord
detects that from the source's own distinct-colour count (past 65,536 it is treated as photographic) and
spends pixels on those instead, saying so on the result line. Between the two — a busy illustration with
gradients, like this site's own 1344×768 social card at 29,004 colours — only the 256 and 128 rungs are
allowed; 64, 32 and 16 push its 99th-percentile colour error to 73, 86 and 147, which is visible banding in
a gradient. You can still force any palette size yourself under PNG colours; that is your call to
make, and it is labelled lossy when you make it.
| Source | Quality | WebP | JPEG | WebP saves |
|---|---|---|---|---|
| Screenshot | 92 | 233.2 KB | 380.3 KB | 38.7% |
| Screenshot | 85 | 182.2 KB | 303.9 KB | 40.0% |
| Screenshot | 60 | 130.5 KB | 197.8 KB | 34.0% |
| Illustration | 85 | 10.9 KB | 24.9 KB | 56.3% |
WebP also keeps transparency, which JPEG cannot. Only on the JPEG fallback does this page paint white behind your image first — without it every transparent pixel would come out black. So a logo with a transparent background keeps its transparency on the WebP path and on the Lossless (PNG) path, and gains a white rectangle only on the JPEG path, which is reached solely when your browser cannot encode WebP at all.
Where WebP is not the obvious answer. Three honest cases. First, compatibility: Discord's own image CDN serves WebP, and the current desktop and web clients preview it inline, but we cannot test every client build or every bot and bridge from here — if a recipient tells you the image showed up as a download link instead of a preview, re-save it as a JPEG. Second, animation: this page draws one frame to a canvas, so an animated GIF or animated WebP comes back as a single still. That is not a bug we can patch here; use the GIF page instead, which plans an animated result. Third, decode cost: WebP and especially AVIF are cheaper to download and more expensive to decode than JPEG, which is a real trade-off on an old phone scrolling a busy channel — a rule of thumb, not something we benchmarked.
And why not AVIF, which is smaller still? Because the browser will not encode it. AVIF usually beats
WebP by a further 20–30% at matched quality (rule of thumb, from the format's published comparisons, not our
measurement) — but that is about AVIF encoders in general, not about anything a web page can reach. We
probed it directly: in Chromium 150, canvas.toDataURL('image/avif') comes back as a
data:image/png URL. The browser does not refuse; it silently hands you PNG instead. Asking for
AVIF on the 1280×2077 screenshot therefore returned a 497.1 KB PNG where WebP returned 233.2 KB. A
silent fallback that doubles the file is worse than not offering the option, so we do not offer it. The day
canvas gains a real AVIF encoder, the probe at the top of this page is the only thing that has to change.
Quality or resolution: what each one takes away
There are only two knobs behind the lossy Auto path, and they fail differently. (Lossless (PNG) has neither of them: there is no quality knob, and since T-SCV.24 resolution is only its second choice — it spends a COLOUR budget first, laddering 256 → 128 → 64 → 32 → 16 palette entries at full size, and drops resolution only when the smallest palette it is allowed to use still misses. On a 1200×900 UI capture measured in this page's own browser test that is a 36.5 KB full-size file against 39.2 KB at 240×180 the old way — smaller and sharp.) Lowering quality keeps every pixel and spends fewer bits describing each one, so detail turns mushy and hard edges — text, UI chrome, cartoon linework — grow halos and blocky rings. Lowering resolution keeps the picture clean and makes it physically smaller, so it looks fine until someone zooms in and finds there is nothing there. Here is the same 1280×2077 screenshot down both roads:
| Pixels | Quality | Measured size |
|---|---|---|
| 1280×2077 | 92 | 233.2 KB |
| 1280×2077 | 60 | 130.5 KB |
| 1280×2077 | 42 | 113.8 KB |
| 896×1454 | 85 | 105.7 KB |
| 640×1039 | 92 | 81.4 KB |
| 640×1039 | 85 | 63.9 KB |
The two rows in the middle are the interesting pair: 113.8 KB for full resolution at quality 42, and 105.7 KB for 70% of each side at quality 85. Practically the same bytes, completely different damage. The first still has every pixel of your 1280-wide screenshot but the text has started ringing; the second is clean and sharp but is now an 896-pixel-wide image that someone will have to squint at. Which one is right depends entirely on the picture, which is why this page does not pretend to know: it steps quality down first, all the way to 42, and only then starts removing pixels — because “I still want the whole thing at full size, slightly softer” is the more common wish. If yours is the other wish, say so with the Resize first — max long edge control: set it to 896 (or 1280, or whatever you actually need on screen) and the planner spends the whole budget on quality at that size instead of on pixels you were never going to look at.
Generation loss is real, but not the way people think. The folk belief is that each re-save halves the file and adds visible mush. We measured the first half of that claim and it is false. Taking this page's own output and feeding it back through the encoder at quality 85, six times in a row, the sizes went 182.2 KB → 178.9 KB → 177.5 KB → 176.7 KB → 176.2 KB → 175.8 KB: a total of 3.5% over six generations, almost all of it in the first pass. The bytes barely move because the encoder is being handed an image whose detail has already been thrown away, so there is little new to discard. What does keep degrading is the picture: every pass re-quantizes an already-quantized image, so the ringing around edges gets a little wider and flat areas get a little blotchier each time, even though your file manager shows nearly the same number. The practical rule: always re-encode from the best original you have, never from something that has already been through a compressor twice.
That is also why re-encoding an already-compressed JPEG disappoints people. Measured here: a 1280×2077 JPEG saved at quality 85 (303.9 KB) dropped in at the free tier came back as a 262.4 KB WebP at full resolution and quality 92 — a 14% saving. That 14% is essentially the format change, not new compression of the picture, and it cost you a second lossy pass to get. If your source is a JPEG that is already comfortably under your limit, the honest advice is to send it as it is.
What this page will not do
It will not invent compression that does not exist. This is a re-encoder, not a magic shrinker. Every byte it saves comes from throwing away picture detail or pixels, or from moving to a better-designed format. A file that is already near its floor for its dimensions barely moves, and — as the 9.9 KB social card above shows — can even grow.
It will not compress harder than one pass of deflate. Lossless (PNG) is a real output path — every pixel and every transparent pixel kept exactly — and it now does both of the cheap things a PNG optimiser does. It builds a palette and writes a genuine indexed (colour-type-3) file when that is smaller, which on the 1344×768 social card measured further up turns 194.0 KB of truecolour into 44.1 KB at 256 colours. And it searches filters: each scanline is scored against all five PNG filter types (None, Sub, Up, Average, Paeth), the image is encoded twice — once with the old filter byte 0 on every row, once with the per-row winners — and the smaller of the two files is the one you get. Ties keep the unfiltered bytes, so the result can never be larger than it was before that search existed. On that social card the search finds another 1.4 KB (3.1%) at 256 colours and nothing at 16; on a 1280×2077 screenshot it finds nothing and costs about 60 ms. Past roughly 4 million bytes of palette data — about a 4-megapixel image at 256 colours — the second encode is skipped rather than made to stall your tab, and you get the unfiltered file. What it still will not do is compress those bytes again: no zopfli, no second compression pass, no trying deflate at other settings. oxipng, pngquant and ImageOptim all do that, so against a PNG one of them has already been over, the file this page writes can still be the bigger one. When the re-encode comes back no smaller than what you dropped in, the verdict says exactly that and the download button hands you your original file instead. Those tools still beat us on that class of file, and we would rather point at them than quietly hand you a worse result.
It will not chase an impossible target at a fixed size — but it will offer you a smaller size. The planner has floors: quality never goes below 42, and the image is never scaled below 20% of each side, because a thumbnail that technically fits is not a result. Those floors set a hard minimum for a given pixel count. For a 4000×3000 image the planner's model puts that minimum at roughly 99 KB, so a 50 KB custom target is out of reach at 4000×3000 — and smallcord does not simply say so from the model. It runs that floor encode for real, shows you the measured size next to your target, and labels the result “Closest attempt” rather than pretending it fits. Then it does the arithmetic the other way round and names the size that would work: for that photo at 50 KB, a 567 px long edge (567×425). One click on “Resize to 567 px and retry” fills in the max-long-edge control and re-encodes — no cropping tool, no second website. The honest cost is still real: you are agreeing to fewer pixels, and 567×425 is a thumbnail, not the photo you started with.
It will not animate, it has no idea what sound is, and it may not open every format. Animated input becomes one still frame; the GIF page is the one that plans animation, and if the file in front of you moves or makes noise the arithmetic is different enough to need its own page — a video is fitted as bitrate × duration split between picture and soundtrack, while an audio file spends that whole budget on one track (a 12-minute 128 kbps stereo MP3 lands about a tenth over the 10 MB free tier and needs ~113 kbps to fit). A still image has no duration to divide by at all, which is why this page solves for quality and pixels instead. Decoding is done by your browser, not by us, so what opens depends on what your browser supports: JPEG, PNG, WebP and GIF everywhere, HEIC/HEIF from an iPhone typically in Safari but not in Chrome or Firefox, and camera RAW files essentially nowhere. When the browser cannot decode a file, you get a plain “your browser rejected the file as an image” instead of a spinner that never ends.
It will not keep your metadata, and it will not send your file anywhere. The output is rebuilt from decoded pixels, so the EXIF block — camera model, capture time, GPS coordinates — is simply not carried over; the one field that matters visually, Orientation, has already been applied by the browser at decode time, so portrait photos come out upright. And there is no server anywhere in the file path: no upload, no account, no queue. The only off-page request this site makes at all is a single cookieless page-view count to our own stats host when a page loads, described in full on the privacy page; it never sees a file. Open your browser's Network tab and choose an image — you will see zero requests. That is the one promise on this page we would rather break the tool than break.
Questions
Does my image get uploaded anywhere?
No. Your browser reads the file from disk, decodes it, draws it to an off-screen canvas and re-encodes it there; the download is a blob that never existed outside your machine. There is no server to receive an image — smallcord is static files — so there is nothing to trust us about: open your browser's Network tab, choose a file, and watch zero requests happen.
Why is the download a .webp and not a .jpg?
Because WebP was smaller in every comparison we measured on the same pixels at the same quality in the same browser — 38.7% smaller than JPEG at quality 92 on a 1280×2077 screenshot, 56.3% smaller at quality 85 on a 1344×768 illustration — and unlike JPEG it keeps transparency. If your browser cannot encode WebP the page detects that at load and falls back to JPEG automatically, and only that JPEG fallback flattens transparent pixels to white. Both of those are the Auto (smallest) path. When you need every pixel kept exactly — line art, pixel art, a QR code, a transparent UI capture — set Output format to Lossless (PNG) and you get a .png back instead, with transparency intact — and it is fitted by spending a colour budget before it will spend a single pixel, so text and line art stay sharp. If a recipient's client shows a download link instead of an inline preview, re-save that one as a JPEG.
Why did my file come out bigger than the one I dropped in?
Because your original was already compressed harder than the settings your budget allows here. When there is plenty of room under your limit the page encodes at quality 92, and quality 92 can easily cost more bytes than whatever the original was saved at — dropping smallcord's own 9.9 KB social card in at the free tier returns 14.2 KB. It happens far more often in Lossless (PNG) mode, because a browser canvas writes a plain truecolour PNG: on our 1280×2077 screenshot that canvas PNG is 497.1 KB against WebP's 233.2 KB. smallcord's indexed-palette pass claws a lot of that back where an image has few enough colours, and it now also scores all five PNG filter types on every scanline and keeps whichever of the two candidate encodings deflates smaller, so its PNG output can never be larger than it was before that search existed. What it still does not do is compress those bytes a second time: no zopfli, no second pass, so a file that oxipng or pngquant has already been over can still grow here. The result line says so plainly when it happens, and in PNG mode the download it offers you is your original file, untouched, not the bigger one.
If I pick 256 colours, is Lossless (PNG) still lossless?
No, and the page says so in those words rather than leaving you to work it out. Picking 256, 64 or 16 under PNG colours quantizes your image to that many colours and writes an indexed PNG, which is lossy in colour: flat fills and hard edges come through untouched, gradients and photographic areas band. Every pixel and every transparent pixel is still there at full resolution — it is the colour range that shrank, not the picture — and the result line names the number it was reduced to. On Auto, colours are only ever reduced for one reason: your file did not fit at full size and Spend colours before pixels found a palette that did, which the result line states as "fitted at full size with 64 colours". When the file already fits, Auto writes an indexed PNG only if your image uses 256 colours or fewer, in which case every colour gets its own palette entry and the file decodes back pixel-identical. For a single dropped image, Auto also encodes the 256-colour version anyway just to tell you what it would have weighed — on smallcord's own 1344×768 social card, 44.1 KB against 194.0 KB truecolour — so declining is an informed choice, not a shrug.
Why did my screenshot come back at full size instead of shrunk?
Because a PNG has two levers and colours are now the first one smallcord spends. A lossless PNG cannot trade sharpness, so before this page will resize your image it tries writing it as an indexed PNG with 256 palette entries, then 128, 64, 32 and 16 — all at your original resolution. It encodes both roads for real and keeps whichever file is smaller, so the result is never bigger than the resized one would have been. In this page's own browser test a 1200×900 UI capture at a 43 KB target comes back at the full 1200×900 and 36,505 B with a 256-colour palette, where resizing alone produced 39,237 B at 240×180 — smaller and still readable. It refuses to do this to photographs: past 65,536 distinct colours smallcord treats the image as photographic and resizes it instead, because on a 900×600 photograph even a 256-colour palette moves the average pixel 14.6 of 255, which is banding you can see. Untick Spend colours before pixels if you would rather always have the resize.
Does re-saving an image over and over destroy it?
The picture degrades, but the file size barely does — which is the opposite of what most people expect. Feeding this page's own output back through the encoder at quality 85 six times in a row measured 182.2 KB, 178.9 KB, 177.5 KB, 176.7 KB, 176.2 KB and 175.8 KB: 3.5% in total, almost all of it on the first pass. Detail keeps going even though the bytes stop moving, so always start from the best original you have rather than from a file that has already been through a compressor.
Can it shrink an animated GIF, or a RAW or HEIC photo?
Animated input comes back as a single still frame, because this page draws one frame to a canvas — use the GIF page instead, which plans an animated result. For stills, decoding is your browser's job, not ours: JPEG, PNG, WebP and GIF work everywhere, HEIC/HEIF from an iPhone usually opens in Safari but not in Chrome or Firefox, and camera RAW files essentially never open. If the browser cannot decode it you get a plain message saying so, not an endless spinner.
What if even the smallest version is still too big?
Then smallcord offers you a smaller version of it, with a real number rather than a guess. In Auto (smallest), quality stops at 42 and the image is never scaled below 20% of each side, so there is a genuine floor for any given pixel count — around 99 KB for a 4000×3000 image, by the planner's model. When your target is under that floor the page still runs the floor encode for real, shows the measured size beside your target, and labels it “Closest attempt” instead of claiming a fit. It then names the long edge that should fit — for that photo at a 50 KB target, 567 px, i.e. 567×425 — and “Resize to 567 px and retry” fills in the max-long-edge control and re-encodes on the spot. No cropping tool, no second website. The number is an estimate from the size just measured, and the retry reports the real bytes; what you are trading away is pixels, so expect a much smaller picture.