PDF.js渲染模糊,效果与viewer.html不一致求解决方案
解决PDF.js渲染PDF模糊的问题
问题根源是基础示例未适配高DPI屏幕的设备像素比(devicePixelRatio),而官方viewer内置了该适配逻辑,导致两者显示效果差异。以下是修复方案:
修改步骤
- 获取当前设备的像素比:
const devicePixelRatio = window.devicePixelRatio || 1;
- 结合设备像素比调整渲染缩放比例,确保canvas生成足够的像素密度:
const scale = 1.5 * devicePixelRatio; const viewport = page.getViewport({ scale: scale });
- 设置canvas的实际像素尺寸和CSS显示尺寸:
- 实际像素尺寸使用乘以像素比后的viewport参数,保证渲染精度
- CSS显示尺寸还原为原始比例下的大小,避免canvas显示过大
const canvas = document.getElementById('the-canvas'); const context = canvas.getContext('2d'); // 实际渲染像素尺寸 canvas.height = viewport.height; canvas.width = viewport.width; // 页面显示尺寸 canvas.style.height = `${viewport.height / devicePixelRatio}px`; canvas.style.width = `${viewport.width / devicePixelRatio}px`;
- 可选:开启canvas高质量图像平滑,进一步优化显示效果:
context.imageSmoothingEnabled = true; context.imageSmoothingQuality = 'high';
完整修复后代码
<script src="//mozilla.github.io/pdf.js/build/pdf.js"></script> <h1>PDF.js 'Hello, world!' example</h1> <canvas id="the-canvas"></canvas>
var url = 'https://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf'; var pdfjsLib = window['pdfjs-dist/build/pdf']; pdfjsLib.GlobalWorkerOptions.workerSrc = '//mozilla.github.io/pdf.js/build/pdf.worker.js'; var loadingTask = pdfjsLib.getDocument(url); loadingTask.promise.then(function(pdf) { console.log('PDF loaded'); var pageNumber = 1; pdf.getPage(pageNumber).then(function(page) { console.log('Page loaded'); const devicePixelRatio = window.devicePixelRatio || 1; var scale = 1.5 * devicePixelRatio; var viewport = page.getViewport({scale: scale}); var canvas = document.getElementById('the-canvas'); var context = canvas.getContext('2d'); canvas.height = viewport.height; canvas.width = viewport.width; canvas.style.height = `${viewport.height / devicePixelRatio}px`; canvas.style.width = `${viewport.width / devicePixelRatio}px`; context.imageSmoothingEnabled = true; context.imageSmoothingQuality = 'high'; var renderContext = { canvasContext: context, viewport: viewport }; var renderTask = page.render(renderContext); renderTask.promise.then(function () { console.log('Page rendered'); }); }); }, function (reason) { console.error(reason); });
原理说明
高DPI屏幕(如Retina屏)的devicePixelRatio大于1,意味着屏幕上1个CSS像素对应多个物理像素。若直接用原始比例渲染,canvas的物理像素数量不足,会导致文字和图形模糊。通过将渲染比例乘以设备像素比,让canvas生成足够的物理像素,再通过CSS将显示尺寸还原,就能在不改变页面布局的前提下,实现高清渲染效果。
内容的提问来源于stack exchange,提问作者lemycanh
相关产品推荐
相关产品推荐

