@brakebein/pdf2png
Version:
Convert pages of a PDF document to PNG images
146 lines (141 loc) • 5.05 kB
JavaScript
;
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