SingleLargePage Feature

This commit is contained in:
Felix Kaspar 2024-08-21 21:11:07 +02:00
parent 1a7e148a78
commit 152daf60fb
3 changed files with 78 additions and 0 deletions

View File

@ -0,0 +1,4 @@
{
"friendlyName": "Single Large Page",
"description": "Merge all pages of a document into a single long page."
}

View File

@ -0,0 +1,18 @@
import { OperatorAvailability, OperatorSchema } from ".";
import Joi from "@stirling-tools/joi";
import { JoiPDFFileSchema } from "../wrappers/PdfFileJoi";
import i18next from "i18next";
export default new OperatorSchema({
joi: {
label: i18next.t("friendlyName", { ns: "singleLargePage" }),
description: i18next.t("description", { ns: "singleLargePage" }),
inputSchema: JoiPDFFileSchema.label(i18next.t("inputs.pdffile.name")).description(i18next.t("inputs.pdffile.description")),
valueSchema: Joi.object({}),
outputSchema: JoiPDFFileSchema.label(i18next.t("outputs.pdffile.name")).description(i18next.t("outputs.pdffile.description")),
},
materialSymbolName: "receipt",
availability: OperatorAvailability.Both
}
);

View File

@ -0,0 +1,56 @@
import { PdfFile, RepresentationType } from "../wrappers/PdfFile";
import { Operator, Progress, oneToOne } from ".";
import { PDFDocument } from "pdf-lib";
export class SingleLargePage extends Operator {
/** Merging pages from multiple pdfs into a singe output document. */
async run(input: PdfFile[], progressCallback: (state: Progress) => void): Promise<PdfFile[]> {
return oneToOne<PdfFile, PdfFile>(input, async (input) => {
const source = await input.pdfLibDocument;
const pages = source.getPages();
const result = await PDFDocument.create();
// Calculate total height and maximum width
let totalHeight = 0;
let maxWidth = 0;
pages.forEach(page => {
const { width, height } = page.getSize();
totalHeight += height;
if (width > maxWidth) {
maxWidth = width;
}
});
// Add a single large page to the new document
const largePage = result.addPage([maxWidth, totalHeight]);
const pageBytes = await source.save();
// Draw each page from the original PDF onto the large page
let currentHeight = 0;
for (const page of pages) {
const { width, height } = page.getSize();
// Embed the original page into the new large page
const [embeddedPage] = await result.embedPdf(pageBytes, [pages.indexOf(page)]);
// Draw the embedded page onto the large page
largePage.drawPage(embeddedPage, {
x: 0,
y: totalHeight - currentHeight - height,
width,
height,
});
currentHeight += height;
}
progressCallback({ curFileProgress: 0, operationProgress: 1 });
return new PdfFile("mergedPDF", result, RepresentationType.PDFLibDocument, "extended_" + input.filename);
});
}
}