离线 · 无上传 · 浏览器本地完成Offline · no uploads · runs in the browser
HTML 转 WebP——离线、一页一图、不上传HTML to WebP offline — one image per A4 page
它与 HTML→JPG 走的是同一条链,只有终点不同:`html>pdf` 把净化后的文档整篇渲染成一张画布,按 A4 的毫米比例算页数(页高 = 画布高 × 210 ÷ 画布宽,每 297 mm 一页向上取整,最后一片按剩余高度收),切成同高片段并**以无损位图(`toDataURL` 的 PNG 那一条)嵌进 PDF**;`pdf>webp` 再把每一页转成一张 WebP。同一条 `createPdfToImageConverter` 工厂同时造出 JPEG 与 WebP 两个终点,所以**产物形状一样**:一页一图、两页以上 ZIP(里面按 `page-N.webp` 编号)、单页直接给一个 `.webp`。不一样的只有编码档位归属:WebP 与 JPEG 同属「有损容器」,质量与目标体积这两个参数对它们生效(`LOSSY_MIME_TYPES`),面板也正是按这一条决定给不给这两格;PNG 那一路则两者都不给、也不会拿去做二次量化。目标体积的追逐顺序是固定的:先把质量沿档位往下走,走不到再把画面缩小重试——所以「文件小了」有两种来路,看页面时值得知道是哪一种。要照实说的边界:这一格不摆密度滑杆(面板只对以 PDF 为输入的转换给它),但密度值会被每一步带走,上一批 PDF 转换留下的值就作用在这里的中间那份 PDF 上;没设过时用默认 144。整页捕获的高度上限 32768 px(一边最大 8192 px 的四倍)超过就明确报错,不给空白画布也不给半张图。图里的文字不是文字:没有文字层,不能选中、搜索或朗读。产物是无透明的白底图(画布按 `#ffffff` 生成、每页嵌入前再铺一次)。远程与相对路径的子资源引用在渲染前剥掉,取不到字节的图片按张数在结果卡披露——被替换的位置画虚线方框,只在克隆那一步失败的直接留空。全程在这个标签页里完成,只有 storage 权限,脚本从头到尾不执行:净化删可执行标记,渲染用的 iframe 只给 `allow-same-origin`、没有 `allow-scripts`。This is the same chain as HTML to JPG with a different last step: `html>pdf` renders the sanitised document into one canvas, computes the page count from the A4 metric ratio (page height = canvas height × 210 ÷ canvas width, rounding up every 297 mm, the last slice cut to what remains), slices it into equal-height strips and **embeds each as a lossless bitmap (the PNG branch of `toDataURL`)**; `pdf>webp` then turns each page into a WebP. One factory, `createPdfToImageConverter`, builds both the JPEG and the WebP end, so **the artifact shape is identical**: one image per page, a ZIP from two pages up with members named `page-N.webp`, a single `.webp` when there is only one. What differs is only which dials belong: WebP and JPEG are the two lossy containers, so quality and a target size mean something here (`LOSSY_MIME_TYPES`) and the panel offers them on exactly that rule, while the PNG route offers neither and does no second quantisation. The chase order is fixed: quality walks down its ladder first, and only then does the picture scale — so “the file got smaller” has two possible causes worth telling apart. The boundaries, plainly: this route exposes no density slider (the panel gives it only to conversions taking a PDF as input), yet a density value is forwarded to every step, so one left from an earlier PDF batch applies to the intermediate PDF here; unset, it uses the default 144. The whole-page capture is bounded at 32768 px of height — four times the 8192 px edge ceiling — and past that the route fails rather than returning a blank canvas or half a picture. Text in the image is not text: no text layer, nothing to select, search or read aloud. The pictures are opaque on white (the canvas is produced on `#ffffff` and each page is filled again before embedding). Sub-resource references to the network or sibling paths are stripped before rendering and unretrievable images are disclosed by count, a replaced spot drawn as a dashed box while one that fails only during cloning is left blank. All of it runs in this tab on the storage permission, and nothing executes: sanitising removes the executable markup and the render frame is sandboxed to `allow-same-origin` with no `allow-scripts`.
这条链路怎么走How the route runs
HTMLHTML PDFPDF WebPWebP
共 2 步,由扩展的路径搜索自动选出,中间产物不落盘。2 steps, chosen by the extension's own path search; intermediate results never touch the disk.
会保留什么What carries over
- 形状与 JPEG 那格一致:一页一图、两页以上 ZIP、成员名 `page-N.webp`The same shape as the JPEG page: one image per page, a ZIP from two pages up, members named `page-N.webp`
- 切片无损:中间那份 PDF 存的是 PNG,压缩只发生在最后转 WebP 这一次Lossless slices: the intermediate PDF stores PNG, so compression happens once, on the final WebP
- 质量与目标体积在这条路上是真档位(WebP 与 JPEG 同属有损容器)Quality and target size are real dials here — WebP and JPEG are the two lossy containers
- 不透明白底:画布按 `#ffffff` 生成、每页嵌入前再铺一次Opaque on white: the canvas is produced on `#ffffff` and every page is filled again before embedding
如实说明的限制What it does not do
- 有损:质量先降、尺寸后降去追目标体积,两种「变小」的来路不一样,看效果时值得区分Lossy: chasing a target size walks quality down first and only then scales the picture — two different reasons for “it got smaller”
- 这一格不摆密度滑杆,但上一批 PDF 转换留下的密度值会被带到这一步;没设过时是默认 144This route exposes no density slider, yet a density left from an earlier PDF batch is forwarded into this step; unset, it is the default 144
- 整页捕获高度上限 32768 px:超过明确报错,不给空白画布或半张图A 32768 px ceiling on the whole-page capture height, failing outright rather than returning a blank canvas or half a picture
- 一次最多渲染 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
- 图里没有文字层:不能选中、搜索或朗读,要这些请保留 HTML 或转 TXT / MarkdownNo text layer: nothing to select, search or read aloud — keep the HTML, or take TXT / Markdown, for that
- 远程与相对路径的图片取不到字节:引用被剥掉、按张数披露,位置是虚线方框或直接留空Images referenced by network address or sibling path have no bytes: the references are stripped, the count is disclosed, and a spot is a dashed box or left blank
实操提示Working with it
- 要严格无损的一张长图:HTML→PNG,整页捕获、没有第二次量化For one exactly-lossless tall image: HTML to PNG, a whole-page capture with no second quantisation
- 要能打印归档的成品:HTML→PDF,页面就是文档本身For a printable document: HTML to PDF, whose pages are the file itself
- 只要其中一页:可以先 HTML→PDF 再用 PDF→WebP 选页,避免整篇都出图For a single page only: HTML to PDF, then PDF to WebP on that file with a page range
常见问题Questions people actually ask
WebP 和 JPEG 这两格该选哪个?WebP or JPEG — which page should I use?
两者的产物形状完全一样(一页一图、多页 ZIP、同一条 A4 切片与同一次有损编码),差别只在容器本身。本项目没有对本机样本做过两套体积对照,所以不宣称哪一种更小——需要小体积就在两格上各跑一次、用同一份文件比字节数,这比听任何保证可靠。The artifact shape is identical (one image per page, a ZIP from two pages up, the same A4 slicing and the same single lossy pass); what differs is only the container. This project has not run a same-file size comparison between the two on this machine, so it claims neither is smaller — run both on your own file and compare byte counts, which beats any guarantee on this page.
为什么我的 WebP 是白底,不是原来网页的深色背景?Why is the WebP on white rather than my page’s dark background?
这一路的画布按 `#ffffff` 生成,每页嵌入 PDF 前还会再铺一次白,而最后那次编码是 JPEG 之外唯一的有损容器、产物不透明。也就是说:页面自己没画出底色的地方,就会落成白。想让某处是别的颜色,请在源文档里真的把那个颜色画出来。The canvas for this route is produced on `#ffffff`, each page is filled white again before it enters the PDF, and the final encode is opaque. So any area the page itself never paints lands as white. To get another colour there, paint it in the source document.
一张很长的网页会出一张超大的 WebP 吗?Will one very long page become one enormous WebP?
不会。中间那份 PDF 是按 A4 切的,所以产出是一组页面图而不是单张长图:两页以上打包成 ZIP,每张的像素尺寸由那一页的排版高度与当时的渲染倍率决定。整篇一次捕获的高度上限 32768 px 仍然管着渲染那一步,超过就报错。No. The intermediate PDF is sliced at A4, so you get a set of page images rather than one long picture: two or more arrive in a ZIP, each sized from that page’s laid-out height and the render scale in force. The 32768 px ceiling still governs the capture step, and exceeding it fails the conversion.
不需要账号,也不需要联网:装好扩展后点图标,在新标签页里打开工作台,文件从磁盘直接选。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.