feat(pdf-to-png): direct download resulting image and adjust filename

This commit is contained in:
Sebastian Espei
2025-11-30 23:45:27 +01:00
parent 2741b29ad1
commit e5cd2e6ab5
2 changed files with 51 additions and 19 deletions

View File

@@ -1,11 +1,18 @@
import { showLoader, hideLoader, showAlert } from '../ui.js';
import { downloadFile, readFileAsArrayBuffer, getPDFDocument } from '../utils/helpers.js';
import {
downloadFile,
readFileAsArrayBuffer,
getPDFDocument,
} from '../utils/helpers.js';
import { state } from '../state.js';
import JSZip from 'jszip';
import * as pdfjsLib from 'pdfjs-dist';
import { PDFPageProxy } from 'pdfjs-dist';
pdfjsLib.GlobalWorkerOptions.workerSrc = new URL('pdfjs-dist/build/pdf.worker.min.mjs', import.meta.url).toString();
pdfjsLib.GlobalWorkerOptions.workerSrc = new URL(
'pdfjs-dist/build/pdf.worker.min.mjs',
import.meta.url
).toString();
export async function pdfToPng() {
showLoader('Converting to PNG...');
@@ -13,26 +20,30 @@ export async function pdfToPng() {
const pdf = await getPDFDocument(
await readFileAsArrayBuffer(state.files[0])
).promise;
const zip = new JSZip();
const qualityInput = document.getElementById('png-quality') as HTMLInputElement;
const qualityInput = document.getElementById(
'png-quality'
) as HTMLInputElement;
const scale = qualityInput ? parseFloat(qualityInput.value) : 2.0;
for (let i = 1; i <= pdf.numPages; i++) {
const page = await pdf.getPage(i);
const viewport = page.getViewport({ scale });
const canvas = document.createElement('canvas');
canvas.height = viewport.height;
canvas.width = viewport.width;
const context = canvas.getContext('2d');
await page.render({ canvasContext: context, viewport: viewport, canvas }).promise;
const blob = await new Promise((resolve) =>
canvas.toBlob(resolve, 'image/png')
if (pdf.numPages === 1) {
downloadFile(
await pageToBlob(await pdf.getPage(1), scale),
getCleanFilename(state.files[0].name) + '.png'
);
} else {
const zip = new JSZip();
for (let i = 1; i <= pdf.numPages; i++) {
const page = await pdf.getPage(i);
zip.file(`page_${i}.png`, await pageToBlob(page, scale));
}
const zipBlob = await zip.generateAsync({ type: 'blob' });
downloadFile(
zipBlob,
getCleanFilename(state.files[0].name) + '_pngs.zip'
);
zip.file(`page_${i}.png`, blob as Blob);
}
const zipBlob = await zip.generateAsync({ type: 'blob' });
downloadFile(zipBlob, 'converted_pngs.zip');
} catch (e) {
console.error(e);
showAlert('Error', 'Failed to convert PDF to PNG.');
@@ -40,3 +51,24 @@ export async function pdfToPng() {
hideLoader();
}
}
async function pageToBlob(page: PDFPageProxy, scale: number): Promise<Blob> {
const viewport = page.getViewport({ scale });
const canvas = document.createElement('canvas');
canvas.height = viewport.height;
canvas.width = viewport.width;
const context = canvas.getContext('2d');
await page.render({
canvasContext: context,
viewport: viewport,
canvas,
}).promise;
const blob = await new Promise((resolve) =>
canvas.toBlob(resolve, 'image/png')
);
return blob as Blob;
}
function getCleanFilename(fileName: string): string {
return fileName.replace(/\.pdf$/i, '');
}