From 3fcf9757f7530eb132537ab36f9f1f40575cc4e4 Mon Sep 17 00:00:00 2001 From: Sebastian Espei Date: Tue, 2 Dec 2025 21:31:19 +0100 Subject: [PATCH] feat(pdf-to-jpg): direct download resulting image and adjust filename --- src/js/logic/pdf-to-jpg.ts | 48 +++++++++++++++++++++++++++----------- src/js/ui.ts | 3 +-- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/js/logic/pdf-to-jpg.ts b/src/js/logic/pdf-to-jpg.ts index a12c102..5ad368b 100644 --- a/src/js/logic/pdf-to-jpg.ts +++ b/src/js/logic/pdf-to-jpg.ts @@ -3,6 +3,7 @@ import { downloadFile, readFileAsArrayBuffer, getPDFDocument } from '../utils/he 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(); @@ -13,29 +14,25 @@ export async function pdfToJpg() { const pdf = await getPDFDocument( await readFileAsArrayBuffer(state.files[0]) ).promise; - const zip = new JSZip(); - + const qualityInput = document.getElementById('jpg-quality') as HTMLInputElement; const quality = qualityInput ? parseFloat(qualityInput.value) : 0.9; + if(pdf.numPages === 1) { + const page = await pdf.getPage(1); + const blob = await pageToBlob(page, quality); + downloadFile(blob, getCleanFilename(state.files[0].name) + '.jpg'); + } else { + const zip = new JSZip(); for (let i = 1; i <= pdf.numPages; i++) { const page = await pdf.getPage(i); - const viewport = page.getViewport({ scale: 2.0 }); - const canvas = document.createElement('canvas'); - const context = canvas.getContext('2d'); - canvas.height = viewport.height; - canvas.width = viewport.width; - - await page.render({ canvasContext: context, viewport: viewport, canvas }).promise; - - const blob = await new Promise((resolve) => - canvas.toBlob(resolve, 'image/jpeg', quality) - ); + const blob = await pageToBlob(page, quality); zip.file(`page_${i}.jpg`, blob as Blob); } const zipBlob = await zip.generateAsync({ type: 'blob' }); - downloadFile(zipBlob, 'converted_images.zip'); + downloadFile(zipBlob, getCleanFilename(state.files[0].name) + '_jpgs.zip'); + } } catch (e) { console.error(e); showAlert( @@ -46,3 +43,26 @@ export async function pdfToJpg() { hideLoader(); } } + +async function pageToBlob(page: PDFPageProxy, quality: number): Promise { + const viewport = page.getViewport({ scale: 2.0 }); + const canvas = document.createElement('canvas'); + const context = canvas.getContext('2d'); + canvas.height = viewport.height; + canvas.width = viewport.width; + + await page.render({ canvasContext: context, viewport: viewport, canvas }).promise; + + const blob = await new Promise((resolve) => + canvas.toBlob(resolve, 'image/jpeg', quality) + ); + return blob as Blob; +} + +function getCleanFilename(fileName: string): string { + let clean = fileName.replace(/\.pdf$/i, '').trim(); + if (clean.length > 80) { + clean = clean.slice(0, 80); + } + return clean; +} diff --git a/src/js/ui.ts b/src/js/ui.ts index 1ac3e21..3703d09 100644 --- a/src/js/ui.ts +++ b/src/js/ui.ts @@ -774,8 +774,7 @@ export const toolTemplates = {

Higher quality = larger file size

-

Click "Download All as ZIP" to get images for all pages.

- + `, 'jpg-to-pdf': () => `