Nén Giảm Dung Lượng File PDF Trong JavaScript & Node.js
Giảm kích thước file PDF bằng cách tối ưu hóa luồng dữ liệu và giảm độ phân giải ảnh với Ghostscript và pdf-lib. Đi kèm file test 50MB.
Các tệp PDF lớn được tạo bởi thiết bị máy quét hoặc công cụ thiết kế đồ họa có thể tiêu tốn băng thông quá mức và vượt quá giới hạn tệp đính kèm email. Nén PDF liên quan đến việc giảm mẫu ảnh raster độ phân giải cao, loại bỏ metadata không cần thiết và nén các luồng font nội tại.
Các Kỹ Thuật Nén PDF
- Giảm mẫu hình ảnh (Image Downsampling): Giảm hình ảnh nhúng từ 300 DPI (in ấn) xuống 150 DPI hoặc 72 DPI (màn hình web).
- Nén Flate Object: Nén các content stream bằng zlib/deflate.
- Xóa Object Mồ Côi: Loại bỏ các subset font không dùng, thumbnail nhúng và lịch sử sửa đổi.
Tải file PDF test 50MB để benchmark tỷ lệ nén và tốc độ xử lý của bạn.
Tải File Mẫu 50MB PDF →Nén PDF Trong Node.js Sử Dụng Ghostscript
Ghostscript vẫn là tiêu chuẩn vàng cho nén luồng PDF với tỷ lệ cao:
import { exec } from 'child_process';
import util from 'util';
import fs from 'fs';
const execAsync = util.promisify(exec);
export async function compressPdfWithGhostscript(
inputPath: string,
outputPath: string,
quality: 'screen' | 'ebook' | 'printer' = 'ebook'
): Promise<{ originalSize: number; compressedSize: number; savingsRatio: string }> {
// -dPDFSETTINGS:
// /screen = chất lượng thấp nhất, kích thước nhỏ nhất (72 dpi)
// /ebook = chất lượng vừa, phù hợp đọc trên web (150 dpi)
// /printer = chất lượng cao (300 dpi)
const gsCommand = [
'gs',
'-sDEVICE=pdfwrite',
'-dCompatibilityLevel=1.4',
`-dPDFSETTINGS=/${quality}`,
'-dNOPAUSE',
'-dQUIET',
'-dBATCH',
`-sOutputFile="${outputPath}"`,
`"${inputPath}"`,
].join(' ');
await execAsync(gsCommand);
const origStats = fs.statSync(inputPath);
const compStats = fs.statSync(outputPath);
const savings = (((origStats.size - compStats.size) / origStats.size) * 100).toFixed(1);
return {
originalSize: origStats.size,
compressedSize: compStats.size,
savingsRatio: `${savings}%`,
};
}
Nén Phía Client Với pdf-lib
Để nén luồng PDF nhẹ trực tiếp trên trình duyệt:
import { PDFDocument } from 'pdf-lib';
export async function optimizePdfInMemory(pdfBytes: Uint8Array): Promise<Uint8Array> {
const pdfDoc = await PDFDocument.load(pdfBytes);
// Lưu lại với tối ưu hóa object stream
return await pdfDoc.save({ useObjectStreams: true });
}
Nguyễn Đại Long
Tác GiảBackend Lead • Chuyên gia Kiến trúc Hệ thống Phân tán & Lưu trữ Đám mây
Hơn 4 năm kinh nghiệm thiết kế các hệ thống xử lý tệp tải lên thông lượng lớn, tối ưu hóa cơ sở dữ liệu và hạ tầng phân tán Cloudflare R2 / AWS S3. Người sáng lập FileDummy và Mạng lưới Hệ sinh thái NDL.
Bài viết này có hữu ích không?
Bấm Thích để ủng hộ tác giả và giúp bài viết lan tỏa tới cộng đồng lập trình viên.
Thảo Luận Kỹ Thuật & Đóng Góp Ý Kiến (0)
Chia sẻ kết quả benchmark, phản hồi các trường hợp biên hoặc đặt câu hỏi chuyên môn.
Chưa có bình luận nào. Hãy là lập trình viên đầu tiên bắt đầu cuộc thảo luận!
Câu Hỏi Thường Gặp (FAQ)
What is the best tool for compressing PDFs in Node.js?▾
Ghostscript achieves 60–80% size reduction on image-heavy PDFs using the ebook or screen quality preset. For pure-code compression without a binary dependency, pdf-lib can remove metadata and optimize object streams, but achieves less dramatic reduction on already-optimized PDFs.
Why does my compressed PDF look blurry?▾
PDF compression primarily downsamples embedded images. The screen preset targets 72dpi (web viewing), which degrades print quality. Use the printer preset (300dpi) for documents that need to be printed.
Can I compress a PDF without losing text quality?▾
Yes. Text and vector graphics are resolution-independent and do not degrade. Only embedded raster images are affected. Use Ghostscript's -dColorImageResolution flag to control image-only downsampling.