Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FEAT: Using Ghostscript for reduce size of big PDFs #4

Merged
merged 6 commits into from
Sep 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions dist/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,9 @@ export declare function rotatePDF(pdfBuffer: Buffer, direction: '90' | '180' | '
*/
export declare function renderPDFPagesToPNG(pdfBuffer: Buffer, firstPage?: number, lastPage?: number, resolution?: number): Promise<Buffer[]>;
export declare function isValidPDF(pdfBuffer: Buffer): Promise<boolean>;
/**
* This function try, reduce size of your PDF not destroying quality
* @param pdfBuffer Buffer
* @returns Buffer
*/
export declare function compressPDF(pdfBuffer: Buffer | string, encoding?: BufferEncoding): Promise<Buffer>;
25 changes: 24 additions & 1 deletion dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.isValidPDF = exports.renderPDFPagesToPNG = exports.rotatePDF = exports.extractPDFPages = exports.countPDFPages = exports.combinePDFs = void 0;
exports.compressPDF = exports.isValidPDF = exports.renderPDFPagesToPNG = exports.rotatePDF = exports.extractPDFPages = exports.countPDFPages = exports.combinePDFs = void 0;
const child_process_1 = __importDefault(require("child_process"));
const fs_extra_1 = __importDefault(require("fs-extra"));
const tempy_1 = __importDefault(require("tempy"));
Expand Down Expand Up @@ -166,3 +166,26 @@ async function isValidPDF(pdfBuffer) {
}
}
exports.isValidPDF = isValidPDF;
/**
* This function try, reduce size of your PDF not destroying quality
* @param pdfBuffer Buffer
* @returns Buffer
*/
async function compressPDF(pdfBuffer, encoding) {
try {
if (typeof pdfBuffer === 'string') {
pdfBuffer = Buffer.from(pdfBuffer, encoding !== null && encoding !== void 0 ? encoding : 'base64');
}
const compressedPdf = await useTempFilesPDFInOut(pdfBuffer, async (input, output) => {
await exec(`gs -q -dNOPAUSE -dBATCH -dSAFER -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen -dEmbedAllFonts=true -dSubsetFonts=true -dColorImageDownsampleType=/Bicubic -dColorImageResolution=144 -dGrayImageDownsampleType=/Bicubic -dGrayImageResolution=144 -dMonoImageDownsampleType=/Bicubic -dMonoImageResolution=144 -sOutputFile=${output} ${input}`);
});
if (pdfBuffer.length < compressedPdf.length) {
return pdfBuffer;
}
return compressedPdf;
}
catch (e) {
throw new Error('Failed optimize PDF: ' + e.message);
}
}
exports.compressPDF = compressPDF;
24 changes: 24 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,3 +201,27 @@ export async function isValidPDF(pdfBuffer: Buffer): Promise<boolean> {
return false;
}
}

/**
* This function try, reduce size of your PDF not destroying quality
* @param pdfBuffer Buffer
* @returns Buffer
*/
export async function compressPDF(pdfBuffer: Buffer | string, encoding?: BufferEncoding): Promise<Buffer> {
try {
if(typeof pdfBuffer === 'string'){
pdfBuffer = Buffer.from(pdfBuffer, encoding ?? 'base64')
}
const compressedPdf = await useTempFilesPDFInOut(pdfBuffer, async (input, output) => {
await exec(
`gs -q -dNOPAUSE -dBATCH -dSAFER -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen -dEmbedAllFonts=true -dSubsetFonts=true -dColorImageDownsampleType=/Bicubic -dColorImageResolution=144 -dGrayImageDownsampleType=/Bicubic -dGrayImageResolution=144 -dMonoImageDownsampleType=/Bicubic -dMonoImageResolution=144 -sOutputFile=${output} ${input}`,
);
});
if (pdfBuffer.length < compressedPdf.length) {
return pdfBuffer;
}
return compressedPdf;
} catch (e: any) {
throw new Error('Failed optimize PDF: ' + e.message);
}
}
12 changes: 12 additions & 0 deletions test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,15 @@ describe('isValidPDF', () => {
expect(await gs.isValidPDF(Buffer.from([1, 2, 3]))).toBe(false);
});
});


describe('compressPDF', () => {
test('returns PDF reduce size send buffer file', async () => {
const optimizedPDF = await gs.compressPDF(files['pdf3.pdf'])
expect(optimizedPDF.length).toBeLessThanOrEqual(files['pdf3.pdf'].length);
});
test('returns PDF reduce size send string encoded file', async () => {
const optimizedPDF = await gs.compressPDF(files['pdf3.pdf'].toString('base64'))
expect(optimizedPDF.length).toBeLessThanOrEqual(files['pdf3.pdf'].length);
});
})