Google Drive 下載供查看文件/PDF Image Quality Tuning
用閱讀器內建的縮放,觀察 natural 是否會變大
有些 viewer 在你把縮放調到 200%/300% 後,會重新渲染產生更大的 bitmap;
- 在閱讀器介面把縮放調到 300%(不是 Ctrl+Plus,而是閱讀器自己的 zoom)。
- 等頁面完全重繪後再跑、確保所有頁面都已經用高解析渲染(避免有些頁還停留在低解析)
Array.from(document.images)
.filter(i=>/^blob:/.test(i.src))
.slice(0,3)
.map(i=>[i.naturalWidth,i.naturalHeight]);
//用閱讀器內建的縮放,觀察 natural 是否會變大
const blobs = Array.from(document.images).filter(i=>/^blob:/.test(i.src));
const uniq = [...new Set(blobs.map(i => `${i.naturalWidth}x${i.naturalHeight}`))];
console.log('unique natural sizes:', uniq, 'count=', blobs.length);
//如果 uniq 裡只有 ["3200x4526"] 類似的一種,就可以匯出。
完整匯出 code(建議 captureScale = 1)
(() => {
const JSPDF_URL = 'https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.2/jspdf.min.js';
// 建議:既然來源已經 3200x4526,很清楚了,就不要再 1.5
const captureScale = 1.0; // 1.0 = 原生高解析;若你硬要更大可改 1.2(不建議 1.5)
const jpegQ = 0.92; // 0.9~0.95 通常夠清楚;1.0 會非常大
const MODE = 'cover'; // 'cover'滿版裁切;'fit'完整不裁切
let policy = null;
if (window.trustedTypes?.createPolicy) {
try {
policy = window.trustedTypes.createPolicy('myJspdfPolicy', {
createScriptURL: (url) => url
});
} catch (e) {
policy = null;
}
}
function getPageSize(pdf) {
const ps = pdf?.internal?.pageSize;
const w = (typeof ps.getWidth === 'function') ? ps.getWidth()
: (typeof ps.width === 'function') ? ps.width()
: ps.width;
const h = (typeof ps.getHeight === 'function') ? ps.getHeight()
: (typeof ps.height === 'function') ? ps.height()
: ps.height;
return { w, h };
}
const script = document.createElement('script');
script.onload = () => {
if (typeof window.jsPDF !== 'function') {
console.error('jsPDF not available on window.');
return;
}
const imgs = Array.from(document.images).filter(img => img?.src && /^blob:/.test(img.src));
console.log('[INFO] blob images =', imgs.length);
if (imgs.length === 0) return;
// 確認解析度
const uniq = [...new Set(imgs.map(i => `${i.naturalWidth}x${i.naturalHeight}`))];
console.log('[INFO] unique natural sizes:', uniq);
const pdf = new window.jsPDF(); // default page size
(async () => {
for (let idx = 0; idx < imgs.length; idx++) {
const img = imgs[idx];
if (idx > 0) pdf.addPage();
const baseW = img.naturalWidth || img.width;
const baseH = img.naturalHeight || img.height;
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = Math.round(baseW * captureScale);
canvas.height = Math.round(baseH * captureScale);
ctx.setTransform(captureScale, 0, 0, captureScale, 0, 0);
ctx.imageSmoothingEnabled = true;
ctx.imageSmoothingQuality = 'high';
ctx.drawImage(img, 0, 0, baseW, baseH);
const imgData = canvas.toDataURL('image/jpeg', jpegQ);
const { w: pageW, h: pageH } = getPageSize(pdf);
const imgW = canvas.width;
const imgH = canvas.height;
const s = (MODE === 'fit')
? Math.min(pageW / imgW, pageH / imgH)
: Math.max(pageW / imgW, pageH / imgH);
const drawW = imgW * s;
const drawH = imgH * s;
const x = (pageW - drawW) / 2;
const y = (pageH - drawH) / 2;
pdf.addImage(imgData, 'JPEG', x, y, drawW, drawH);
if (idx % 5 === 0) await new Promise(r => setTimeout(r, 0));
if (idx % 10 === 0) console.log(`[INFO] rendered ${idx + 1}/${imgs.length}`);
}
pdf.save('download.pdf');
console.log('[OK] saved download.pdf');
})();
};
script.onerror = (e) => console.error('Failed to load jsPDF:', e);
script.src = policy ? policy.createScriptURL(JSPDF_URL) : JSPDF_URL;
document.head.appendChild(script);
})();
一個網頁入面以圖片形式顯示嘅內容(大量 blob: 圖)打包成 PDF 方便離線睇同整理。一開始我以為「調高 JPEG quality」或者「做 150% 截圖」就會變清,點知點搞都仲係糊。最後發現真正關鍵唔係壓縮,而係來源解析度。
以下係我成個思路同做法總結(偏工程角度)。
結果見到:
- display(畫面顯示):例如 1200×1697
- natural(實際像素):竟然只有 800×1131
即係話:頁面上嗰張圖本身就係低解析預覽,瀏覽器只係放大顯示,文字邊緣自然「糊」。
所以:
jpegQ = 1.0只會令檔案更大,唔會令文字更利captureScale = 1.5只係放大模糊(插值),唔會增加細節
但當我用閱讀器/預覽器嘅縮放功能(有啲平台會重新渲染頁面)令頁面重新載入高解析 bitmap 之後,再跑同一段 code,竟然變成:
[3200, 4526]
呢刻我就知:而家先有得匯出高質 PDF。因為 3200×4526 已經接近可用嘅高 DPI(尤其係文字頁)。
重點:唔係你後端匯出時拉大,而係要令「源頭圖」本身就高解析。
#破解Google雲端檢視者無法下載PDF檔案
#Google共用PDF檔檢視者無法下載的方法