diff --git a/CHANGELOG.md b/CHANGELOG.md index 7fea455..63668af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## 2024-05-16 + +### ✨ Improvements + +- Added a quality setting to the card extraction dialog. Can be used to optimize for file size or image quality. Optimizing for file size will greatly reduce the size of the generated PDF (and the speed of extraction and generation) at the cost of some slight quality reduction on the card images (JPEG vs lossless PNG). However it should usually not matter and thus is now the default. Implements #2. + +### 🐛 Bug fixes + +- The output PDF will now be removed again before generating a new one. + ## 2024-05-15 ### ✨ Improvements diff --git a/assets/cardfoldr.js b/assets/cardfoldr.js index 1199697..1dae5e1 100644 --- a/assets/cardfoldr.js +++ b/assets/cardfoldr.js @@ -279,7 +279,8 @@ const rotateImage180 = async (image) => { ctx.rotate(Math.PI); ctx.drawImage(img, -img.width / 2, -img.height / 2); - const src = canvas.toDataURL(); + const mimeType = image.startsWith("data:image/png") ? "image/png" : "image/jpeg"; + const src = canvas.toDataURL(mimeType); return src; } @@ -298,8 +299,8 @@ const extractCards = async () => { const marginY = parseFloat(document.getElementById('marginY').value); const backLoc = document.getElementById('backs').value; - const rotateBacks = document.getElementById('rotateBacks').checked; + const optimizeFor = document.getElementById('optimize').value; const scale = 4; const orientationClass = (width > height) ? "landscape" : "portrait"; @@ -307,6 +308,7 @@ const extractCards = async () => { clearCards(); const cardsContainer = document.getElementById('cards'); + const mimeType = optimizeFor === "quality" ? "image/png" : "image/jpeg"; let expectedTotal; if (backLoc === "lastpage") { @@ -334,7 +336,7 @@ const extractCards = async () => { await page.render({ canvasContext: ctx, viewport }).promise; const cardImage = document.createElement('img'); - cardImage.src = canvas.toDataURL(); + cardImage.src = canvas.toDataURL(mimeType); cardImage.className = "front"; cardImage.style = `aspect-ratio: ${width} / ${height}`; @@ -386,7 +388,7 @@ const extractCards = async () => { await backsPage.render({ canvasContext: ctx, viewport }).promise; - const src = rotateBacks ? await rotateImage180(canvas.toDataURL()) : canvas.toDataURL(); + const src = rotateBacks ? await rotateImage180(canvas.toDataURL(mimeType)) : canvas.toDataURL(mimeType); for (let i = 1; i < count; i++) { const cardImage = document.getElementById(`card-${i}`).getElementsByClassName('back')[0]; @@ -409,7 +411,7 @@ const extractCards = async () => { await backPage.render({ canvasContext: ctx, viewport }).promise; const cardImage = document.getElementById(`card-${backCount}`).getElementsByClassName('back')[0]; - cardImage.src = rotateBacks ? await rotateImage180(canvas.toDataURL()) : canvas.toDataURL(); + cardImage.src = rotateBacks ? await rotateImage180(canvas.toDataURL(mimeType)) : canvas.toDataURL(mimeType); backCount++; } @@ -434,7 +436,7 @@ const extractCards = async () => { await backPage.render({ canvasContext: ctx, viewport }).promise; const cardImage = document.getElementById(`card-${backCount}`).getElementsByClassName('back')[0]; - cardImage.src = rotateBacks ? await rotateImage180(canvas.toDataURL()) : canvas.toDataURL(); + cardImage.src = rotateBacks ? await rotateImage180(canvas.toDataURL(mimeType)) : canvas.toDataURL(mimeType); backCount++; } @@ -453,7 +455,7 @@ const extractCards = async () => { await backPage.render({ canvasContext: ctx, viewport }).promise; const cardImage = document.getElementById(`card-${backCount}`).getElementsByClassName('back')[0]; - cardImage.src = rotateBacks ? await rotateImage180(canvas.toDataURL()) : canvas.toDataURL(); + cardImage.src = rotateBacks ? await rotateImage180(canvas.toDataURL(mimeType)) : canvas.toDataURL(mimeType); backCount++; } diff --git a/assets/worker.js b/assets/worker.js index bf9b5b9..c4c22fe 100644 --- a/assets/worker.js +++ b/assets/worker.js @@ -268,7 +268,11 @@ if (typeof importScripts === "function") { const deduplicationLUT = {}; const lookupCard = async (card) => { if (!deduplicationLUT[card]) { - deduplicationLUT[card] = await pdfDoc.embedPng(card); + if (card.startsWith("data:image/png;base64,")) { + deduplicationLUT[card] = await pdfDoc.embedPng(card); + } else { + deduplicationLUT[card] = await pdfDoc.embedJpg(card); + } } return deduplicationLUT[card]; } diff --git a/index.html b/index.html index 9b89f10..4133e8e 100644 --- a/index.html +++ b/index.html @@ -174,6 +174,14 @@