离线 · 无上传 · 浏览器本地完成Offline · no uploads · runs in the browser
JSON 转 JPG——离线、A4 分页逐页编码、不上传JSON to JPG offline — A4 pages, no upload
这条路的形状与 PNG 那一格不同,而且差别是**路由里写明的**:`json>html` 之后,同为图片目标的 JPEG 先走 `html>pdf` 再走 `pdf>jpg`,而不是「截一张长图再压缩」。理由写在 `html-to-pdf.ts` 的注释里——`html→png→jpg` 交回的是按页面宽度排布的一条长带,而一份要分享或打印的 JSON 快照通常需要页边界;所以这条链在终点相同的比较里显式让 `html>pdf` 优先(`edgePreference`)。产物有三个具体后果:**一页一图**,长文件出多张并以 ZIP 交付;**中间那份 PDF 的页面是无损位图**(逐页 PNG 数据 URL 再嵌进文档),有损只发生在最后那一次 JPEG 编码;**折行仍由页面宽度决定**,长字符串在页内断开,断开的样子进图。可调的是质量与最长边,编码前按 `clampQuality` / `clampMaxEdge` 再钳一次,因为它们也可能来自存储而不是这次点选。与 PNG 那一格共享的边界也还在:整页渲染高度上限 32768 px、查看器不含远程引用、图片里没有可复制的文字。全过程在这个标签页里完成,只有 storage 权限。This route has a different shape from the PNG page, and the difference is **stated in the routing**: after `json>html`, a JPEG target goes through `html>pdf` and then `pdf>jpg` rather than “capture one tall image and compress it”. The reason is in the comment at `html-to-pdf.ts` — `html→png→jpg` hands back a single strip laid out at page width, while a JSON snapshot meant for sharing or printing usually wants page boundaries, so the tie between the two image ends is broken explicitly in favour of `html>pdf` (`edgePreference`). Three concrete consequences: **one image per page**, so a long file yields several pictures delivered in a ZIP; **the PDF in the middle carries lossless bitmaps** (each page is PNG data URL before it is embedded), so the only lossy step is the final JPEG encode; and **layout still decides wrapping**, since long strings break inside the page and that broken-up look is what gets imaged. Quality and the longest edge are adjustable and re-clamped before encoding by `clampQuality` / `clampMaxEdge`, because those values can also arrive from storage rather than from this click. The boundaries shared with the PNG page remain: a 32768 px ceiling on rendered page height, a viewer with no remote reference, and no copyable text inside an image. All of it inside this tab on the storage permission.
这条链路怎么走How the route runs
JSONJSON HTMLHTML PDFPDF JPEGJPEG
共 3 步,由扩展的路径搜索自动选出,中间产物不落盘。3 steps, chosen by the extension's own path search; intermediate results never touch the disk.
会保留什么What carries over
- 按 A4 分页、一页一 JPEG:每张都是完整的一页,而不是一条被切开的长带A4 pages, one JPEG each: every picture is a whole page rather than a slice of one long strip
- 只有一次有损:中间那份 PDF 的页面是无损 PNG,压缩只发生在最后交给 JPEG 的那一次Only one lossy step: the PDF in the middle holds lossless PNG pages, so compression happens once, on the way out
- 语法着色与折叠摘要按渲染结果进图,看起来就是你在浏览器里看到的那份查看器Syntax colouring and fold summaries enter the image as rendered, so it looks like the viewer you saw in the browser
- 质量与最长边可调,并在编码前按同一套边界再钳一次(存储里的值也钳)Quality and the longest edge are adjustable and re-clamped against the same bounds before encoding, including values coming from storage
如实说明的限制What it does not do
- 多页会打包成 ZIP:一份长 JSON 可能出十几张编号图片,只想要一张长图请走 JSON→PNGSeveral pages arrive as a ZIP: a long JSON can produce a dozen numbered pictures, so take JSON to PNG when you want one tall image
- 一次最多渲染 200 页(`MAX_PDF_IMAGE_PAGES`):超过就报「要渲染的页数过多」,并让你用页码范围只选需要的页或先把文件拆开——每一页在编码前各自占着一张全尺寸画布,200 页已经是数百 MB,再往前是标签页自己崩掉,那比一条错误难说清得多At most 200 pages rasterise in one pass (`MAX_PDF_IMAGE_PAGES`): past that the route reports “too many pages to render at once” and points at a page range or splitting the file — every page holds a full-size canvas until it is encoded, 200 of them is already hundreds of megabytes, and beyond that the tab crashes itself, which is far harder to explain than an error
- JPEG 是有损的:等宽字形的细边与语法着色的小面积色块会留下压缩痕迹,低对比的那类最敏感JPEG is lossy: thin monospace edges and the small colour fields of syntax highlighting show artefacts, and low-contrast pairs suffer most
- 文字进图就不可选:产物没有文字层,不能搜索也不能复制;要这些请走 JSON→TXT / HTML / MarkdownText inside an image is not selectable: there is no text layer to search or copy; take JSON to TXT, HTML or Markdown for that
- 整页渲染高度上限 32768 px 仍然适用,超限报错而不是交付被截短的内容The 32768 px ceiling on rendered page height still applies, and exceeding it reports failure instead of delivering trimmed content
- 不承诺能再解析回 JSON:这一格交付的是给人看的快照,不是数据交换格式No promise that it parses back to JSON: this page delivers a snapshot for people to read, not a data format
实操提示Working with it
- 想要一张不分页的长图:JSON→PNG,同一条渲染链的另一半For one unpaginated tall image: JSON to PNG, the other half of the same rendering chain
- 想要成品文档:JSON→PDF,页面就是文档本身、还能继续打印For a finished document: JSON to PDF, whose pages are the artifact and still print
- 想要小体积又可读:先看 JSON→HTML 的渲染,再决定是截长图还是分页For the smallest readable result: look at JSON to HTML first, then decide between a tall shot and pages
常见问题Questions people actually ask
为什么不干脆把长图压成 JPEG,而要分页?Why page it instead of just compressing the tall image?
因为那条路交回的是按页面宽度排布的一条长带,而这条取舍写在路由里:同分的图片终点由 `edgePreference` 排序(`html>pdf` 是 0、`html>png` 是 10,小的排前面),不是实现顺带的后果。分页给的是页边界与一页一图,长图给的是单次捕获。Because that route hands back a single strip laid out at page width, and the choice is written into the routing: the tie between the two image ends is ordered by `edgePreference` (0 on `html>pdf`, 10 on `html>png`, lower first), not an accident of implementation. Paging buys page bounds and one picture per page; the tall capture buys a single canvas.
一次有损和两次有损,差别在哪里?One lossy step or two — where is the difference?
中间那份 PDF 的页面是无损 PNG,所以文字与色块在渲染之后只被 JPEG 编过一次。若中间先出 JPEG 再出 JPEG,细字与着色边界会被压两次——这条链刻意避开那种形状。The PDF in the middle holds lossless PNG pages, so your glyphs and colour fields are JPEG-encoded exactly once after rendering. Going JPEG to JPEG would crush thin strokes and highlight edges twice, which is the shape this chain avoids.
长文件会得到几个文件?How many files does a long document produce?
一页一张,张数由排版后的总高度除以页高决定;两张以上时产物是一个 ZIP。想要单份文件,请走 JSON→PNG(一张长图)或 JSON→PDF(一份文档)。One picture per page, the count set by the laid-out height divided by page height, and two or more arrive inside a ZIP. For a single file take JSON to PNG (one tall image) or JSON to PDF (one document).
不需要账号,也不需要联网:装好扩展后点图标,在新标签页里打开工作台,文件从磁盘直接选。No account and no network: install the extension, click its icon, and the workbench opens in a new tab reading straight off your disk.
从 Chrome 应用商店安装Install from the Chrome Web Store 安装步骤Install steps GitHub 源码Source on GitHub
要把它压到指定体积?Need it under a target size? The 图片压缩工具image compressor可以在浏览器里重编码 PNG / JPEG / WebP。 re-encodes PNG / JPEG / WebP in the browser.