perf: optimize PDF to image conversion by using a single Ghostscript execution and improve cleanup logic
Build and Push Multi-Platform Images / build-and-push (push) Successful in 28s
Build and Push Multi-Platform Images / build-and-push (push) Successful in 28s
This commit is contained in:
@@ -37,16 +37,37 @@ export class PdfService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Konvertiert alle Seiten einer PDF in Bilder.
|
* Konvertiert alle Seiten einer PDF in Bilder.
|
||||||
|
* Verwendet einen einzigen Ghostscript-Aufruf mit %d-Platzhalter für alle Seiten.
|
||||||
*/
|
*/
|
||||||
async pdfToImages(pdfPath: string, dpi = 200): Promise<string[]> {
|
async pdfToImages(pdfPath: string, dpi = 200): Promise<string[]> {
|
||||||
const pageCount = await this.getPageCount(pdfPath);
|
const pageCount = await this.getPageCount(pdfPath);
|
||||||
const images: string[] = [];
|
if (pageCount === 0) return [];
|
||||||
|
|
||||||
|
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'pdf-'));
|
||||||
|
const outputPattern = path.join(tmpDir, 'page-%d.png');
|
||||||
|
|
||||||
|
await execFileAsync('gs', [
|
||||||
|
'-dNOPAUSE',
|
||||||
|
'-dBATCH',
|
||||||
|
'-dSAFER',
|
||||||
|
'-sDEVICE=png16m',
|
||||||
|
`-r${dpi}`,
|
||||||
|
`-sOutputFile=${outputPattern}`,
|
||||||
|
pdfPath,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const images: string[] = [];
|
||||||
for (let i = 1; i <= pageCount; i++) {
|
for (let i = 1; i <= pageCount; i++) {
|
||||||
const imgPath = await this.pdfPageToImage(pdfPath, i, dpi);
|
const imgPath = path.join(tmpDir, `page-${i}.png`);
|
||||||
|
try {
|
||||||
|
await fs.access(imgPath);
|
||||||
images.push(imgPath);
|
images.push(imgPath);
|
||||||
|
} catch {
|
||||||
|
this.logger.warn(`Ghostscript hat Seite ${i} nicht erstellt: ${imgPath}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.logger.debug(`PDF konvertiert: ${images.length}/${pageCount} Seite(n) in ${tmpDir}`);
|
||||||
return images;
|
return images;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,17 +103,16 @@ export class PdfService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Räumt temporäre Bilder auf.
|
* Räumt temporäre Bilder und ihre Verzeichnisse auf.
|
||||||
*/
|
*/
|
||||||
async cleanup(imagePaths: string[]): Promise<void> {
|
async cleanup(imagePaths: string[]): Promise<void> {
|
||||||
|
const dirs = new Set<string>();
|
||||||
for (const imgPath of imagePaths) {
|
for (const imgPath of imagePaths) {
|
||||||
try {
|
try { await fs.unlink(imgPath); } catch {}
|
||||||
await fs.unlink(imgPath);
|
dirs.add(path.dirname(imgPath));
|
||||||
const dir = path.dirname(imgPath);
|
}
|
||||||
|
for (const dir of dirs) {
|
||||||
await fs.rmdir(dir).catch(() => {});
|
await fs.rmdir(dir).catch(() => {});
|
||||||
} catch {
|
|
||||||
// Ignorieren
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user