-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcompress.html
More file actions
288 lines (273 loc) · 15 KB
/
Copy pathcompress.html
File metadata and controls
288 lines (273 loc) · 15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="theme-color" content="#0d0f0c" />
<meta name="format-detection" content="telephone=no, date=no, address=no, email=no" />
<link rel="preload" href="vendor/fonts/ibmplexmono-400.woff2" as="font" type="font/woff2" crossorigin />
<link rel="preload" href="vendor/fonts/fraunces-normal-300.woff2" as="font" type="font/woff2" crossorigin />
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data: blob:; font-src 'self'; connect-src 'self' https://api.counterapi.dev https://formsubmit.co; object-src 'none'; base-uri 'self'; form-action 'self' https://formsubmit.co;" />
<meta name="referrer" content="strict-origin-when-cross-origin" />
<title>Compress a PDF to 100KB, 1MB, or a target size — ClientPDF</title>
<meta name="description" content="Shrink a PDF's file size by re-encoding its images, entirely in your browser. Pick a target size — under 100KB, 500KB, 1MB, or 5MB. Nothing is uploaded, ever." />
<link rel="canonical" href="https://abyworkings-coder.github.io/clientpdf/compress.html" />
<meta property="og:type" content="website" />
<meta property="og:title" content="Compress a PDF to 100KB, 1MB, or a target size — ClientPDF" />
<meta property="og:description" content="Shrink a PDF's file size by re-encoding its embedded images, entirely in your browser. Pick a target size and ClientPDF steps quality down until it fits." />
<meta property="og:url" content="https://abyworkings-coder.github.io/clientpdf/compress.html" />
<meta property="og:site_name" content="ClientPDF" />
<meta property="og:image" content="https://abyworkings-coder.github.io/clientpdf/og-image.jpg" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Compress a PDF to 100KB, 1MB, or a target size — ClientPDF" />
<meta name="twitter:description" content="Shrink a PDF's file size by re-encoding its embedded images, entirely in your browser." />
<meta name="twitter:image" content="https://abyworkings-coder.github.io/clientpdf/og-image.jpg" />
<link rel="icon" href="./logo.svg" type="image/svg+xml" />
<link rel="icon" href="./favicon-32.png" sizes="32x32" type="image/png" />
<link rel="icon" href="./favicon-16.png" sizes="16x16" type="image/png" />
<link rel="apple-touch-icon" href="./apple-touch-icon.png" />
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "SoftwareApplication",
"name": "ClientPDF Compress",
"url": "https://abyworkings-coder.github.io/clientpdf/compress.html",
"applicationCategory": "UtilitiesApplication",
"operatingSystem": "Any (runs in browser)",
"description": "Shrink a PDF's file size by re-encoding its embedded images, entirely in your browser. Nothing is uploaded, ever.",
"offers": {
"@type": "Offer",
"price": "0",
"priceCurrency": "USD"
}
}
</script>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Home",
"item": "https://abyworkings-coder.github.io/clientpdf/"
},
{
"@type": "ListItem",
"position": 2,
"name": "Tools",
"item": "https://abyworkings-coder.github.io/clientpdf/tools.html"
},
{
"@type": "ListItem",
"position": 3,
"name": "Compress PDF",
"item": "https://abyworkings-coder.github.io/clientpdf/compress.html"
}
]
}
</script>
<script type="application/ld+json">{
"@context": "https://schema.org",
"@type": "HowTo",
"name": "How to compress a PDF online without uploading it",
"description": "Shrink a PDF's file size by re-encoding its embedded JPEG images, entirely in your browser.",
"datePublished": "2026-07-27",
"dateModified": "2026-08-05",
"step": [
{
"@type": "HowToStep",
"position": 1,
"name": "Drop one PDF",
"text": "Drag and drop a single PDF file onto the page, or click to browse."
},
{
"@type": "HowToStep",
"position": 2,
"name": "Optionally pick a target size",
"text": "Choose 'Under 100 KB', 'Under 500 KB', 'Under 1 MB', 'Under 5 MB', or 'No target — best quality'. ClientPDF re-encodes JPEG-filtered images embedded in the PDF and, if a target is set, automatically steps quality and max dimension down and retries until the file fits or hits a quality floor."
},
{
"@type": "HowToStep",
"position": 3,
"name": "Click Compress PDF",
"text": "ClientPDF re-encodes JPEG-filtered images embedded in the PDF at a smaller size — starting at quality 0.65 with the longest edge capped at 1600px via a canvas round-trip — then rebuilds the file around the smaller images."
},
{
"@type": "HowToStep",
"position": 4,
"name": "Review the before/after size",
"text": "The tool shows the real result of the compression pass, tells you if a target size was hit, and reports when there was nothing photographic to shrink."
},
{
"@type": "HowToStep",
"position": 5,
"name": "Download the compressed PDF",
"text": "Save the smaller file to your device."
}
]
}</script>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "How do I compress a PDF to a specific size, like 100KB or 1MB?",
"acceptedAnswer": { "@type": "Answer", "text": "Pick a target from the size options after you drop your file — Under 100 KB, Under 500 KB, Under 1 MB, or Under 5 MB. ClientPDF re-encodes the PDF's images at the default quality first, then automatically steps quality and max image dimension down in stages and re-runs until the result fits the target or hits a quality floor, so you don't have to guess and re-download repeatedly." }
},
{
"@type": "Question",
"name": "What happens if my PDF can't reach the target size I picked?",
"acceptedAnswer": { "@type": "Answer", "text": "If the smallest version ClientPDF can produce without severe quality loss is still over your target, it says so plainly and hands you that smallest version instead of silently failing or faking a number. This is usually because the PDF has little or no compressible JPEG content — see 'Why didn't my PDF shrink?' below." }
}
]
}
</script>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<a class="skip-link" href="#main-content">Skip to main content</a>
<noscript><div class="noscript-banner">ClientPDF requires JavaScript — all files are processed locally in your browser and never uploaded. Please enable JavaScript to use these tools.</div></noscript>
<div class="grain"></div>
<header class="topbar">
<div class="wrap topbar-inner">
<div class="brand">
<span class="brand-mark">◆</span>
<span class="brand-name">Client<em>PDF</em></span>
</div>
<nav class="toolnav" aria-label="Tools">
<a href="./index.html">Merge</a>
<a href="./split.html">Split</a>
<a href="./delete-pages.html">Delete Pages</a>
<a href="./duplicate-pages.html">Duplicate Pages</a>
<a href="./insert-pages.html">Insert Blank Pages</a>
<a href="./rotate.html">Rotate</a>
<a href="./reorder.html">Reorder</a>
<a href="./compress.html" aria-current="page">Compress</a>
<a href="./page-numbers.html">Page Numbers</a>
<a href="./images-to-pdf.html">Images to PDF</a>
<a href="./extract-images.html">Extract Images</a>
<a href="./pdf-to-jpg.html">PDF to JPG</a>
<a href="./watermark.html">Watermark</a>
<a href="./metadata.html">Metadata</a>
<a href="./crop.html">Crop Pages</a>
<a href="./resize.html">Resize Pages</a>
<a href="./grayscale.html">Grayscale PDF</a>
<a href="./border.html">Page Borders</a>
<a href="./image-watermark.html">Image Watermark</a>
<a href="./flatten.html">Flatten Form Fields</a>
<a href="./fill-form.html">Fill Form Fields</a>
<a href="./bookmarks.html">Add Bookmarks</a>
<a href="./split-by-bookmarks.html">Split by Bookmarks</a>
<a href="./pages-per-sheet.html">Pages per Sheet</a>
<a href="./redact.html">Redact</a>
<a href="./tools.html">All Tools</a>
<a href="./guide.html">Guide</a>
</nav>
<div class="topbar-status">
<span class="dot" aria-hidden="true"></span>
<span>running locally in this tab — nothing uploaded</span>
</div>
</div>
</header>
<main class="wrap" id="main-content" tabindex="-1">
<section class="hero">
<h1>Open DevTools.<br />Compress this PDF.<br />Watch nothing get sent anywhere.</h1>
<p class="lede">
Re-encodes the JPEG images embedded in a PDF at a smaller size and rebuilds
the file — all inside this tab. Zero network requests after the page loads,
same rule as every other tool here. Check the Network tab yourself.
</p>
<p class="lede">
Need to hit a specific number — under 100KB for a form upload, under 1MB for
an email attachment limit? Pick a target size below and ClientPDF will
automatically step image quality down in stages and retry until your file
fits, instead of leaving you to guess and re-run manually.
</p>
</section>
<section class="tool" id="tool">
<div class="dropzone" id="dropzone" tabindex="0" role="button" aria-label="Add a PDF file">
<input type="file" id="fileInput" accept="application/pdf" hidden />
<div class="dropzone-inner">
<span class="dropzone-icon">⇣</span>
<p><strong>Drop one PDF here</strong> or click to browse</p>
<p class="dropzone-hint">One file at a time · stays on this device</p>
</div>
</div>
<div class="split-panel" id="compressPanel" hidden>
<div class="split-meta" id="compressMeta"></div>
<div class="field-row" id="targetSizeRow">
<label>Target size</label>
<div class="field-radio-group" id="targetSizeGroup" role="radiogroup" aria-label="Target size">
<label><input type="radio" name="targetSize" value="0" checked /> No target — best quality</label>
<label><input type="radio" name="targetSize" value="100" /> Under 100 KB</label>
<label><input type="radio" name="targetSize" value="500" /> Under 500 KB</label>
<label><input type="radio" name="targetSize" value="1024" /> Under 1 MB</label>
<label><input type="radio" name="targetSize" value="5120" /> Under 5 MB</label>
</div>
</div>
</div>
<ol class="file-list" id="fileList" aria-label="Loaded file"></ol>
<div class="actions" id="actions" hidden>
<button class="btn btn-ghost" id="clearBtn" type="button">Clear</button>
<button class="btn btn-primary" id="compressBtn" type="button">
<span id="compressBtnLabel">Compress PDF</span>
</button>
</div>
<div class="result" id="result" role="status" aria-live="polite" hidden></div>
</section>
<section class="proof">
<h2 class="sr-only">Why trust this tool</h2>
<div class="proof-live" id="proofLive">
<span class="proof-live-dot" aria-hidden="true"></span>
<span id="proofLiveText">0 network requests since page load · verified live, not our word for it</span>
</div>
<div class="proof-grid">
<div class="proof-item">
<h3>No accounts</h3>
<p>No signup, no email, no watermark. Use it and close the tab.</p>
</div>
<div class="proof-item">
<h3>Honest results</h3>
<p>Only JPEG images embedded in the PDF are re-encoded. If there's nothing
to shrink, we'll tell you instead of faking a number.
<a href="./guide-compress.html">Why didn't my PDF shrink?</a></p>
</div>
</div>
</section>
<section class="pro" id="pro">
<div class="pro-card">
<div class="pro-copy">
<h2>Splitting, rotating, reordering, or numbering a PDF? All live too.</h2>
<p><a href="./split.html">Extract pages or split every page into its own file</a>, <a href="./rotate.html">fix pages scanned sideways</a>, <a href="./reorder.html">drag pages into a new order</a>, or <a href="./page-numbers.html">stamp page numbers onto every page</a> — same rule: everything stays local. Leave your email and we'll let you know about a Pro batch mode.</p>
</div>
<form class="pro-form" id="proForm">
<input type="email" id="proEmail" placeholder="you@company.com" required aria-label="Email address" autocomplete="email" />
<button class="btn btn-primary" type="submit">Notify me</button>
</form>
<p class="pro-note" id="proNote" role="status" aria-live="polite" hidden>Thanks — saved locally for now, we'll be in touch once signups are live.</p>
</div>
</section>
<section class="about">
<h2>What "compress" means here, specifically</h2>
<p>This tool re-encodes JPEG-filtered images (the <code>/DCTDecode</code> streams) embedded in a PDF at a smaller size — starting at quality 0.65 with the longest edge capped at 1600px, via a canvas round-trip — then rebuilds the file around the smaller images. Images with transparency or a CMYK color space are skipped rather than guessed at, and if a re-encode wouldn't actually come out smaller, it's skipped too. The before/after size shown is always the real result of that pass, never a display trick.</p>
<p>Pick a target size (100 KB, 500 KB, 1 MB, 5 MB) instead of "no target" and the tool re-runs the same re-encode with quality and the max dimension stepped down in stages — 0.65 → 0.5 → 0.35, 1600px → 1200px → 900px — checking the real output size after every pass, until the file fits your target or hits a quality floor around 0.3. If it still can't reach your target without visibly damaging the images, it tells you that plainly and gives you the smallest version it could produce, rather than pretending it hit the number.</p>
<p>If your file comes back close to its original size, that almost always means one of two things: it's mostly text or vector content with nothing photographic to shrink, or its images are already PNG/lossless-encoded rather than JPEG. <a href="./guide-compress.html">This walks through exactly which of those applies to your file, and what to try instead.</a> And if the PDF was already so large it struggled to load before you even clicked Compress, <a href="./guide-large-file-freeze.html">here's why, since that's a browser-memory limit compress itself can't get around.</a></p>
</section>
</main>
<footer class="footer">
<div class="wrap footer-inner">
<span>ClientPDF — built by <a href="https://github.com/abyworkings-coder" target="_blank" rel="noopener">Auto Company</a></span>
<span>No servers were harmed in the making of this tool.</span>
<span class="footer-legal"><a href="./privacy.html">Privacy</a> · <a href="./terms.html">Terms</a></span>
</div>
</footer>
<script src="./counter.js"></script>
<script type="module" src="compress.js"></script>
</body>
</html>