UNPKG

@brakebein/pdf2png

Version:

Convert pages of a PDF document to PNG images

146 lines (141 loc) 5.05 kB
'use strict'; var node_url = require('node:url'); var promises = require('node:fs/promises'); var node_fs = require('node:fs'); var tmp = require('tmp-promise'); var axios = require('axios'); var node_child_process = require('node:child_process'); var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null; function exec(command, options) { return new Promise((resolve, reject) => { node_child_process.exec(command, options, (err, stdout, stderr) => { if (err) { reject({ ...err, stdout, stderr }); } else { resolve({ stdout, stderr }); } }); }); } function execFile(command, args, options) { return new Promise((resolve, reject) => { node_child_process.execFile(command, args, options, (err, stdout, stderr) => { if (err) { reject({ ...err, stdout, stderr }); } else { resolve({ stdout, stderr }); } }); }); } class PdfConvert { constructor(source, options) { this.source = source; this.options = { resolution: 600, ghostscriptPath: new node_url.URL('./executables/ghostscript', (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))).pathname.replace(/^\//, ''), ...options, }; if (process.platform === 'win32') { const suffix = ';' + this.options.ghostscriptPath; const key = process.env.Path ? 'Path' : 'PATH'; if (!new RegExp(suffix.replace('/', '\\/')).test(process.env[key] || '')) { process.env[key] += suffix; } } } async convertPageToImage(page) { await this.writePDFToTemp(); if (!this.tmpFile) { throw new Error('No temporary pdf file!'); } try { const tmpImage = await tmp.file(); await execFile('gs', [ '-dQUIET', '-dPARANOIDSAFER', '-dBATCH', '-dNOPAUSE', '-dNOPROMPT', '-sDEVICE=png16m', '-dTextAlphaBits=4', '-dGraphicsAlphaBits=4', `-r${this.options.resolution}`, `-dFirstPage=${page}`, `-dLastPage=${page}`, `-sOutputFile=${tmpImage.path}`, this.tmpFile.path, ]); const buffer = await promises.readFile(tmpImage.path); await tmpImage.cleanup(); return buffer; } catch (err) { throw new Error('Unable to process image from page: ' + err); } } async getPageCount() { await this.writePDFToTemp(); if (!this.tmpFile) { throw new Error('No temporary pdf file!'); } try { const { stdout } = await exec(`gs -q -dNODISPLAY -c "(${this.tmpFile.path.replace(/\\/g, '/')}) (r) file runpdfbegin pdfpagecount = quit"`); return stdout ? parseInt(stdout.toString().substr(0, stdout.length - 1)) : 0; } catch (err) { throw new Error('Unable to get page count: ' + err); } } async writePDFToTemp() { if (this.tmpFile) return; try { this.tmpFile = await tmp.file(); } catch (err) { throw new Error(`Unable to open tmp file: ` + err); } if (typeof this.source === 'string') { if (/^https?:\/\//.test(this.source)) { try { const response = await axios.get(this.source, { responseType: 'stream', }); const stream = node_fs.createWriteStream(this.tmpFile.path); response.data.pipe(stream); await new Promise((resolve, reject) => { stream.on('finish', resolve); stream.on('error', reject); }); } catch (err) { throw new Error('Unable to fetch file from web location: ' + err); } } else { await promises.copyFile(this.source, this.tmpFile.path); } } else { try { await promises.writeFile(this.tmpFile.path, this.source); } catch (err) { throw new Error('Unable to write tmp file: ' + err); } } } async dispose() { if (this.tmpFile) { await this.tmpFile.cleanup(); this.tmpFile = undefined; } } } exports.PdfConvert = PdfConvert; //# sourceMappingURL=index.cjs.map