-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpdf2img.js
112 lines (93 loc) · 2.83 KB
/
pdf2img.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
const fs = require("fs").promises;
const gm = require("gm").subClass({ imageMagick: true });
const path = require("path");
const util = require("util");
const exec = util.promisify(require("child_process").exec);
class Pdf2Img {
constructor() {
this.options = {
type: "jpg",
density: 600,
outputdir: "",
outputname: "",
page: null,
};
}
setOptions(opts) {
Object.assign(this.options, opts);
}
getOptions() {
return this.options;
}
async convert(input) {
if (path.extname(input) !== ".pdf") {
throw new Error("Unsupported file type.");
}
try {
await fs.access(input);
} catch (error) {
throw new Error("Input file not found.");
}
const output = path.basename(input, ".pdf");
const outputDir = this.options.outputdir || `${output}/`;
try {
await fs.mkdir(outputDir, { recursive: true });
} catch (error) {
// Handle error if any, maybe log it but not necessary to stop the process
}
this.options.outputname = this.options.outputname || output;
const pages = await this.getPageCount(input);
const conversionPromises = pages.map((page) =>
this.convertPage(input, page, outputDir)
);
return Promise.all(conversionPromises);
}
async getPageCount(input) {
const cmd = `gm identify -format "%p " "${input}"`;
const { stdout: pageCountString } = await exec(cmd);
const pages = pageCountString.match(/[0-9]+/g).map(Number);
if (!pages.length) {
throw new Error("Could not determine page count.");
}
if (this.options.page !== null) {
if (this.options.page > 0 && this.options.page <= pages.length) {
return [this.options.page];
} else {
throw new Error("Invalid page number.");
}
}
return pages;
}
async convertPage(input, page, outputDir) {
const outputFile = path.join(
outputDir,
`${this.options.outputname}_${page}.${this.options.type}`
);
const pageSpecificInput = `${input}[${page - 1}]`;
return new Promise((resolve, reject) => {
gm(pageSpecificInput)
.density(this.options.density, this.options.density)
.quality(100)
.write(outputFile, async (err) => {
if (err) {
return reject(new Error("Failed to write output file."));
}
try {
const stats = await fs.stat(outputFile);
if (stats.size === 0) {
return reject(new Error("Zero sized output image detected."));
}
resolve({
page,
name: path.basename(outputFile),
size: stats.size / 1000.0,
path: outputFile,
});
} catch (error) {
reject(new Error("Error accessing output file."));
}
});
});
}
}
module.exports = Pdf2Img;