Files
digitalcatalog/client/src/pdf.ts
T

75 lines
2.4 KiB
TypeScript

import * as pdfjs from "pdfjs-dist";
import pdfWorker from "pdfjs-dist/build/pdf.worker.min.mjs?url";
import { LIMITS, fileTooLargeMessage, tooManyPagesMessage } from "@shared/types";
pdfjs.GlobalWorkerOptions.workerSrc = pdfWorker;
function canvasToJpeg(canvas: HTMLCanvasElement): Promise<Blob> {
return new Promise((resolve, reject) => {
canvas.toBlob(
(blob) => {
if (!blob) reject(new Error("تبدیل تصویر ناموفق بود"));
else resolve(blob);
},
"image/jpeg",
LIMITS.jpegQuality / 100,
);
});
}
export async function renderPdfToJpegs(
file: File,
onProgress?: (done: number, total: number) => void,
): Promise<Blob[]> {
if (file.size > LIMITS.maxFileBytes) {
throw new Error(fileTooLargeMessage(file.size));
}
const data = new Uint8Array(await file.arrayBuffer());
let pdf;
try {
pdf = await pdfjs.getDocument({ data }).promise;
} catch (err) {
const name =
err && typeof err === "object" && "name" in err
? String((err as { name: string }).name)
: "";
if (name === "PasswordException") {
throw new Error("این PDF رمزگذاری شده است و قابل تبدیل نیست.");
}
if (name === "InvalidPDFException") {
throw new Error("این فایل یک PDF معتبر نیست.");
}
throw err;
}
if (pdf.numPages < 1) {
throw new Error("این PDF صفحه‌ای برای نمایش ندارد.");
}
if (pdf.numPages > LIMITS.maxPages) {
throw new Error(tooManyPagesMessage(pdf.numPages));
}
const pages: Blob[] = [];
onProgress?.(0, pdf.numPages);
for (let i = 1; i <= pdf.numPages; i++) {
const page = await pdf.getPage(i);
const base = page.getViewport({ scale: 1 });
const scale = Math.min(LIMITS.maxPageWidth / base.width, 2);
const viewport = page.getViewport({ scale });
const canvas = document.createElement("canvas");
canvas.width = Math.floor(viewport.width);
canvas.height = Math.floor(viewport.height);
const ctx = canvas.getContext("2d");
if (!ctx) throw new Error("تبدیل تصویر ناموفق بود");
const renderTask = page.render({
canvasContext: ctx,
canvas,
viewport,
} as Parameters<typeof page.render>[0]);
await renderTask.promise;
pages.push(await canvasToJpeg(canvas));
onProgress?.(i, pdf.numPages);
}
return pages;
}