文件格式任意转换助手Transfer Any File

离线 · 无上传 · 浏览器本地完成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.

一批转换结果卡片,含文件名、体积与下载入口
一次混合批量,一个 ZIP 下载One mixed batch, one ZIP download

这条链路怎么走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.