diff --git a/build.gradle b/build.gradle index ae51be50f..1d40aa7f7 100644 --- a/build.gradle +++ b/build.gradle @@ -21,8 +21,9 @@ dependencies { //general PDF implementation 'org.apache.pdfbox:pdfbox:2.0.27' + implementation 'com.itextpdf:itextpdf:5.5.13.3' - + developmentOnly("org.springframework.boot:spring-boot-devtools") } diff --git a/src/main/java/stirling/software/SPDF/controller/CompressController.java b/src/main/java/stirling/software/SPDF/controller/CompressController.java index 6e72b09ce..d8028a757 100644 --- a/src/main/java/stirling/software/SPDF/controller/CompressController.java +++ b/src/main/java/stirling/software/SPDF/controller/CompressController.java @@ -1,23 +1,15 @@ package stirling.software.SPDF.controller; -import java.awt.Graphics2D; -import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; import java.io.IOException; -import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; -import javax.imageio.ImageIO; - -import org.apache.pdfbox.cos.COSName; -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.PDPage; -import org.apache.pdfbox.pdmodel.PDResources; -import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.http.HttpStatus; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; @@ -26,30 +18,8 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; -import com.itextpdf.text.DocumentException; -import com.itextpdf.text.pdf.PdfReader; -import com.itextpdf.text.pdf.PdfStamper; - -import stirling.software.SPDF.utils.PdfUtils; import stirling.software.SPDF.utils.ProcessExecutor; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.multipart.MultipartFile; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - @Controller public class CompressController { diff --git a/src/main/java/stirling/software/SPDF/controller/CropController.java b/src/main/java/stirling/software/SPDF/controller/CropController.java deleted file mode 100644 index 70371d016..000000000 --- a/src/main/java/stirling/software/SPDF/controller/CropController.java +++ /dev/null @@ -1,66 +0,0 @@ -package stirling.software.SPDF.controller; - -import java.awt.Graphics2D; -import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; - -import javax.imageio.ImageIO; - -import org.apache.pdfbox.cos.COSName; -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.PDPage; -import org.apache.pdfbox.pdmodel.PDResources; -import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.multipart.MultipartFile; - -import com.itextpdf.text.DocumentException; -import com.itextpdf.text.pdf.PdfReader; -import com.itextpdf.text.pdf.PdfStamper; - -import stirling.software.SPDF.utils.PdfUtils; -import stirling.software.SPDF.utils.ProcessExecutor; - -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.multipart.MultipartFile; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - - -@Controller -public class CropController { - - private static final Logger logger = LoggerFactory.getLogger(CropController.class); - - @GetMapping("/crop-pdf") - public String compressPdfForm(Model model) { - model.addAttribute("currentPage", "crop-pdf"); - return "crop-pdf"; - } - - -} diff --git a/src/main/java/stirling/software/SPDF/controller/OCRController.java b/src/main/java/stirling/software/SPDF/controller/OCRController.java index 5425b2c46..93e0f6eb0 100644 --- a/src/main/java/stirling/software/SPDF/controller/OCRController.java +++ b/src/main/java/stirling/software/SPDF/controller/OCRController.java @@ -1,10 +1,8 @@ package stirling.software.SPDF.controller; -import java.io.BufferedReader; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -13,11 +11,12 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; @@ -28,13 +27,6 @@ import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.ModelAndView; import stirling.software.SPDF.utils.ProcessExecutor; - -import java.io.FileOutputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; //import com.spire.pdf.*; @Controller public class OCRController { diff --git a/src/main/java/stirling/software/SPDF/controller/SignController.java b/src/main/java/stirling/software/SPDF/controller/SignController.java deleted file mode 100644 index 8f6ad4046..000000000 --- a/src/main/java/stirling/software/SPDF/controller/SignController.java +++ /dev/null @@ -1,66 +0,0 @@ -package stirling.software.SPDF.controller; - -import java.awt.Graphics2D; -import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; - -import javax.imageio.ImageIO; - -import org.apache.pdfbox.cos.COSName; -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.PDPage; -import org.apache.pdfbox.pdmodel.PDResources; -import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.multipart.MultipartFile; - -import com.itextpdf.text.DocumentException; -import com.itextpdf.text.pdf.PdfReader; -import com.itextpdf.text.pdf.PdfStamper; - -import stirling.software.SPDF.utils.PdfUtils; -import stirling.software.SPDF.utils.ProcessExecutor; - -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.multipart.MultipartFile; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - - -@Controller -public class SignController { - - private static final Logger logger = LoggerFactory.getLogger(SignController.class); - - @GetMapping("/sign-pdf") - public String compressPdfForm(Model model) { - model.addAttribute("currentPage", "sign-pdf"); - return "sign-pdf"; - } - - -} diff --git a/src/main/java/stirling/software/SPDF/controller/SplitPDFController.java b/src/main/java/stirling/software/SPDF/controller/SplitPDFController.java index e159effcd..0eb0429e6 100644 --- a/src/main/java/stirling/software/SPDF/controller/SplitPDFController.java +++ b/src/main/java/stirling/software/SPDF/controller/SplitPDFController.java @@ -1,7 +1,6 @@ package stirling.software.SPDF.controller; import java.io.ByteArrayOutputStream; -import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -10,7 +9,6 @@ import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -108,7 +106,7 @@ public class SplitPDFController { document.close(); // create the zip file - Path zipFile = Paths.get("split_documents.zip"); + Path zipFile = Files.createTempFile("split_documents", ".zip"); URI uri = URI.create("jar:file:" + zipFile.toUri().getPath()); Map env = new HashMap<>(); env.put("create", "true"); @@ -132,7 +130,7 @@ public class SplitPDFController { logger.info("Successfully created zip file with split documents: {}", zipFile.toString()); byte[] data = Files.readAllBytes(zipFile); ByteArrayResource resource = new ByteArrayResource(data); - new File("split_documents.zip").delete(); + Files.delete(zipFile); // return the Resource in the response return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + file.getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_split.zip").contentType(MediaType.APPLICATION_OCTET_STREAM) .contentLength(resource.contentLength()).body(resource); diff --git a/src/main/java/stirling/software/SPDF/controller/converters/ConvertImgPDFController.java b/src/main/java/stirling/software/SPDF/controller/converters/ConvertImgPDFController.java index dd8415d08..8d0d43b26 100644 --- a/src/main/java/stirling/software/SPDF/controller/converters/ConvertImgPDFController.java +++ b/src/main/java/stirling/software/SPDF/controller/converters/ConvertImgPDFController.java @@ -38,12 +38,13 @@ public class ConvertImgPDFController { } @PostMapping("/img-to-pdf") - public ResponseEntity convertToPdf(@RequestParam("fileInput") MultipartFile file) throws IOException { + public ResponseEntity convertToPdf(@RequestParam("fileInput") MultipartFile[] file, + @RequestParam(defaultValue = "false", name = "stretchToFit") boolean stretchToFit, + @RequestParam(defaultValue = "true", name = "autoRotate") boolean autoRotate) throws IOException { // Convert the file to PDF and get the resulting bytes - byte[] bytes = PdfUtils.convertToPdf(file.getInputStream()); - logger.info("File {} successfully converted to pdf", file.getOriginalFilename()); - - return PdfUtils.bytesToWebResponse(bytes, file.getOriginalFilename().replaceFirst("[.][^.]+$", "")+ "_coverted.pdf"); + System.out.println(stretchToFit); + byte[] bytes = PdfUtils.imageToPdf(file, stretchToFit, autoRotate); + return PdfUtils.bytesToWebResponse(bytes, file[0].getOriginalFilename().replaceFirst("[.][^.]+$", "")+ "_coverted.pdf"); } @PostMapping("/pdf-to-img") diff --git a/src/main/java/stirling/software/SPDF/controller/converters/ConvertOfficeController.java b/src/main/java/stirling/software/SPDF/controller/converters/ConvertOfficeController.java index 00996dc06..708f3df2b 100644 --- a/src/main/java/stirling/software/SPDF/controller/converters/ConvertOfficeController.java +++ b/src/main/java/stirling/software/SPDF/controller/converters/ConvertOfficeController.java @@ -1,9 +1,6 @@ package stirling.software.SPDF.controller.converters; -import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; @@ -17,9 +14,7 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.servlet.ModelAndView; -import stirling.software.SPDF.LibreOfficeListener; import stirling.software.SPDF.utils.PdfUtils; import stirling.software.SPDF.utils.ProcessExecutor; @Controller diff --git a/src/main/java/stirling/software/SPDF/utils/PdfUtils.java b/src/main/java/stirling/software/SPDF/utils/PdfUtils.java index 18825a503..030f9e2b5 100644 --- a/src/main/java/stirling/software/SPDF/utils/PdfUtils.java +++ b/src/main/java/stirling/software/SPDF/utils/PdfUtils.java @@ -8,6 +8,7 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.file.Files; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -28,6 +29,7 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.web.multipart.MultipartFile; import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; @@ -37,49 +39,100 @@ public class PdfUtils { private static final Logger logger = LoggerFactory.getLogger(PdfUtils.class); - public static byte[] convertToPdf(InputStream imageStream) throws IOException { - - // Create a File object for the image - File imageFile = new File("image.jpg"); - - try (FileOutputStream fos = new FileOutputStream(imageFile); InputStream input = imageStream) { - byte[] buffer = new byte[1024]; - int len; - // Read from the input stream and write to the file - while ((len = input.read(buffer)) != -1) { - fos.write(buffer, 0, len); - } - logger.info("Image successfully written to file: {}", imageFile.getAbsolutePath()); - } catch (IOException e) { - logger.error("Error writing image to file: {}", imageFile.getAbsolutePath(), e); - throw e; - } - + public static byte[] imageToPdf(MultipartFile[] files, boolean stretchToFit, boolean autoRotate) throws IOException { try (PDDocument doc = new PDDocument()) { - // Create a new PDF page - PDPage page = new PDPage(); - doc.addPage(page); + for (MultipartFile file : files) { + // Create a temporary file for the image + File imageFile = Files.createTempFile("image", ".jpg").toFile(); - // Create an image object from the image file - PDImageXObject image = PDImageXObject.createFromFileByContent(imageFile, doc); + try (FileOutputStream fos = new FileOutputStream(imageFile); InputStream input = file.getInputStream()) { + byte[] buffer = new byte[1024]; + int len; + // Read from the input stream and write to the file + while ((len = input.read(buffer)) != -1) { + fos.write(buffer, 0, len); + } + logger.info("Image successfully written to file: {}", imageFile.getAbsolutePath()); + } catch (IOException e) { + logger.error("Error writing image to file: {}", imageFile.getAbsolutePath(), e); + throw e; + } - try (PDPageContentStream contentStream = new PDPageContentStream(doc, page)) { - // Draw the image onto the page - contentStream.drawImage(image, 0, 0); - logger.info("Image successfully added to PDF"); - } catch (IOException e) { - logger.error("Error adding image to PDF", e); - throw e; + // Create a new PDF page + PDPage page = new PDPage(); + doc.addPage(page); + + // Create an image object from the image file + PDImageXObject image = PDImageXObject.createFromFileByContent(imageFile, doc); + + float pageWidth = page.getMediaBox().getWidth(); + float pageHeight = page.getMediaBox().getHeight(); + + if (autoRotate && ((image.getWidth() > image.getHeight() && pageHeight > pageWidth) || (image.getWidth() < image.getHeight() && pageWidth > pageHeight))) { + // Rotate the page 90 degrees if the image better fits the page in landscape orientation + page.setRotation(90); + pageWidth = page.getMediaBox().getHeight(); + pageHeight = page.getMediaBox().getWidth(); + } + + try (PDPageContentStream contentStream = new PDPageContentStream(doc, page)) { + if (stretchToFit) { + if (page.getRotation() == 0 || page.getRotation() == 180) { + // Stretch the image to fit the whole page + contentStream.drawImage(image, 0, 0, pageWidth, pageHeight); + } else { + // Adjust the width and height of the page when rotated + contentStream.drawImage(image, 0, 0, pageHeight, pageWidth); + } + logger.info("Image successfully added to PDF, stretched to fit page"); + } else { + // Ensure the image fits the page but maintain the image's aspect ratio + float imageAspectRatio = (float) image.getWidth() / (float) image.getHeight(); + float pageAspectRatio = pageWidth / pageHeight; + + // Determine the scale factor to fit the image onto the page + float scaleFactor = 1.0f; + if (imageAspectRatio > pageAspectRatio) { + // Image is wider than the page, scale to fit the width + scaleFactor = pageWidth / image.getWidth(); + } else { + // Image is taller than the page, scale to fit the height + scaleFactor = pageHeight / image.getHeight(); + } + + // Calculate the position of the image on the page + float xPos = (pageWidth - (image.getWidth() * scaleFactor)) / 2; + float yPos = (pageHeight - (image.getHeight() * scaleFactor)) / 2; + + // Draw the image onto the page + if (page.getRotation() == 0 || page.getRotation() == 180) { + contentStream.drawImage(image, xPos, yPos, image.getWidth() * scaleFactor, image.getHeight() * scaleFactor); + } else { + // Adjust the width and height of the page when rotated + contentStream.drawImage(image, yPos, xPos, image.getHeight() * scaleFactor, image.getWidth() * scaleFactor); + } + logger.info("Image successfully added to PDF, maintaining aspect ratio"); + } + } catch (IOException e) { + logger.error("Error adding image to PDF", e); + throw e; + } + + // Delete the temporary file + imageFile.delete(); } // Create a ByteArrayOutputStream to save the PDF to ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); doc.save(byteArrayOutputStream); logger.info("PDF successfully saved to byte array"); + return byteArrayOutputStream.toByteArray(); } + } + public static byte[] convertFromPdf(byte[] inputStream, String imageType, ImageType colorType, boolean singleImage, int DPI) throws IOException, Exception { try (PDDocument document = PDDocument.load(new ByteArrayInputStream(inputStream))) { diff --git a/src/main/java/stirling/software/SPDF/utils/ProcessExecutor.java b/src/main/java/stirling/software/SPDF/utils/ProcessExecutor.java index e244d4a2a..73d597dcc 100644 --- a/src/main/java/stirling/software/SPDF/utils/ProcessExecutor.java +++ b/src/main/java/stirling/software/SPDF/utils/ProcessExecutor.java @@ -1,13 +1,11 @@ package stirling.software.SPDF.utils; +import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.util.Arrays; -import java.util.List; -import java.io.BufferedReader; import java.util.ArrayList; +import java.util.List; public class ProcessExecutor { public static int runCommandWithOutputHandling(List command) throws IOException, InterruptedException { ProcessBuilder processBuilder = new ProcessBuilder(command); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 88844ae41..266a0f350 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -16,4 +16,9 @@ server.error.include-stacktrace=always server.error.include-exception=true server.error.include-message=always -server.servlet.session.tracking-modes=cookie \ No newline at end of file +server.servlet.session.tracking-modes=cookie + +spring.devtools.restart.enabled=true +spring.devtools.livereload.enabled=true + +spring.thymeleaf.encoding=UTF-8 \ No newline at end of file diff --git a/src/main/resources/messages_ar_AR.properties b/src/main/resources/messages_ar_AR.properties index 9e66580c8..dfacb7172 100644 --- a/src/main/resources/messages_ar_AR.properties +++ b/src/main/resources/messages_ar_AR.properties @@ -95,7 +95,7 @@ settings.downloadOption.title=\u062A\u062D\u062F\u064A\u062F \u062E\u064A\u0627\ settings.downloadOption.1=\u0641\u062A\u062D \u0641\u064A \u0646\u0641\u0633 \u0627\u0644\u0646\u0627\u0641\u0630\u0629 settings.downloadOption.2=\u0641\u062A\u062D \u0641\u064A \u0646\u0627\u0641\u0630\u0629 \u062C\u062F\u064A\u062F\u0629 settings.downloadOption.3=\u062A\u0646\u0632\u064A\u0644 \u0627\u0644\u0645\u0644\u0641 -settings.zip=\u0645\u0644\u0641\u0627\u062A \u0627\u0644\u062A\u0646\u0632\u064A\u0644 \u0627\u0644\u0645\u062A\u0639\u062F\u062F \u0627\u0644\u0645\u0636\u063A\u0648\u0637\u0629 +settings.zipThreshold=\u0645\u0644\u0641\u0627\u062A \u0645\u0636\u063A\u0648\u0637\u0629 \u0639\u0646\u062F \u062A\u062C\u0627\u0648\u0632 \u0639\u062F\u062F \u0627\u0644\u0645\u0644\u0641\u0627\u062A \u0627\u0644\u062A\u064A \u062A\u0645 \u062A\u0646\u0632\u064A\u0644\u0647\u0627 #OCR OCR.title = OCR diff --git a/src/main/resources/messages_de_DE.properties b/src/main/resources/messages_de_DE.properties index 28daca8c6..eff421c70 100644 --- a/src/main/resources/messages_de_DE.properties +++ b/src/main/resources/messages_de_DE.properties @@ -4,32 +4,32 @@ # the direction that the language is written (ltr = left to right, rtl = right to left) language.direction=ltr -pdfPrompt=PDF auswählen -multiPdfPrompt=PDFs auswählen(2+) -multiPdfDropPrompt=Wählen Sie alle gewünschten PDFs aus (oder ziehen Sie sie per Drag & Drop hierhin) -imgPrompt=Wählen Sie ein Bild +pdfPrompt=PDF auswählen +multiPdfPrompt=PDFs auswählen(2+) +multiPdfDropPrompt=Wählen Sie alle gewünschten PDFs aus (oder ziehen Sie sie per Drag & Drop hierhin) +imgPrompt=Wählen Sie ein Bild genericSubmit=Einreichen -processTimeWarning=Achtung: Abhängig von der Dateigröße kann dieser Prozess bis zu einer Minute dauern +processTimeWarning=Achtung: Abhängig von der Dateigröße kann dieser Prozess bis zu einer Minute dauern pageOrderPrompt=Seitenreihenfolge (Geben Sie eine durch Komma getrennte Liste von Seitenzahlen ein): goToPage=Los true=Wahr false=Falsch unknown=Unbekannt save=Speichern -close=Schließen +close=Schließen ############# # HOME-PAGE # ############# -home.desc=Ihr lokal gehosteter One-Stop-Shop für alle Ihre PDF-Anforderungen. +home.desc=Ihr lokal gehosteter One-Stop-Shop für alle Ihre PDF-Anforderungen. navbar.convert=Konvertieren navbar.security=Sicherheit navbar.other=Anderes navbar.darkmode=Dark Mode -home.merge.title=PDFs zusammenführen -home.merge.desc=Mehrere PDF-Dateien zu einer einzigen zusammenführen. +home.merge.title=PDFs zusammenführen +home.merge.desc=Mehrere PDF-Dateien zu einer einzigen zusammenführen. home.split.title=PDFs aufteilen home.split.desc=PDFs in mehrere Dokumente aufteilen. @@ -44,75 +44,75 @@ home.pdfToImage.title=PDF zu Bild home.pdfToImage.desc=Konvertieren Sie ein PDF in ein Bild (PNG, JPEG, GIF). home.pdfOrganiser.title=PDF organisieren -home.pdfOrganiser.desc=Seiten entfernen und Seitenreihenfolge ändern. +home.pdfOrganiser.desc=Seiten entfernen und Seitenreihenfolge ändern. -home.addImage.title=Bild einfügen -home.addImage.desc=Fügt ein Bild an eine bestimmte Stelle im PDF ein (Work in progress). +home.addImage.title=Bild einfügen +home.addImage.desc=Fügt ein Bild an eine bestimmte Stelle im PDF ein (Work in progress). -home.watermark.title=Wasserzeichen hinzufügen -home.watermark.desc=Fügen Sie ein eigenes Wasserzeichen zu Ihrem PDF hinzu. +home.watermark.title=Wasserzeichen hinzufügen +home.watermark.desc=Fügen Sie ein eigenes Wasserzeichen zu Ihrem PDF hinzu. home.remove-watermark.title=Wasserzeichen entfernen home.remove-watermark.desc=Wasserzeichen aus Ihrem PDF-Dokument entfernen. -home.permissions.title=Berechtigungen ändern -home.permissions.desc=Die Berechtigungen für Ihr PDF-Dokument verändern. +home.permissions.title=Berechtigungen ändern +home.permissions.desc=Die Berechtigungen für Ihr PDF-Dokument verändern. home.removePages.title=Seiten entfernen home.removePages.desc=Ungewollte Seiten aus dem PDF entfernen. -home.addPassword.title=Passwort hinzufügen -home.addPassword.desc=Das PDF mit einem Passwort verschlüsseln. +home.addPassword.title=Passwort hinzufügen +home.addPassword.desc=Das PDF mit einem Passwort verschlüsseln. home.removePassword.title=Passwort entfernen home.removePassword.desc=Den Passwortschutz eines PDFs entfernen. home.compressPdfs.title=PDF komprimieren -home.compressPdfs.desc=PDF komprimieren um die Dateigröße zu reduzieren. +home.compressPdfs.desc=PDF komprimieren um die Dateigröße zu reduzieren. -home.changeMetadata.title=Metadaten ändern -home.changeMetadata.desc=Ändern/Entfernen/Hinzufügen von Metadaten aus einem PDF-Dokument +home.changeMetadata.title=Metadaten ändern +home.changeMetadata.desc=Ändern/Entfernen/Hinzufügen von Metadaten aus einem PDF-Dokument home.fileToPDF.title=Datei in PDF konvertieren home.fileToPDF.desc=Konvertieren Sie nahezu jede Datei in PDF (DOCX, PNG, XLS, PPT, TXT und mehr) -home.ocr.title=OCR auf PDF ausführen -home.ocr.desc=Scannt und erkennt Text aus Bildern in einer PDF-Datei und fügt ihn erneut als Text hinzu. +home.ocr.title=OCR auf PDF ausführen +home.ocr.desc=Scannt und erkennt Text aus Bildern in einer PDF-Datei und fügt ihn erneut als Text hinzu. home.extractImages.title=Bilder extrahieren home.extractImages.desc=Extrahiert alle Bilder aus einer PDF-Datei und speichert sie als Zip-Datei navbar.settings=Einstellungen settings.title=Einstellungen -settings.update=Update verfügbar +settings.update=Update verfügbar settings.appVersion=App-Version: -settings.downloadOption.title=Download-Option wählen (für einzelne Dateien, die keine Zip-Downloads sind): -settings.downloadOption.1=Im selben Fenster öffnen -settings.downloadOption.2=In neuem Fenster öffnen +settings.downloadOption.title=Download-Option wählen (für einzelne Dateien, die keine Zip-Downloads sind): +settings.downloadOption.1=Im selben Fenster öffnen +settings.downloadOption.2=In neuem Fenster öffnen settings.downloadOption.3=Datei herunterladen -settings.zip=Dateien mit mehrfachem Download zippen +settings.zipThreshold=Dateien komprimieren, wenn die Anzahl der heruntergeladenen Dateien überschritten wird #OCR ocr.title=OCR ocr.header=OCR (Optische Zeichenerkennung) -ocr.selectText.1=Wählen Sie die Sprachen aus, die in der PDF-Datei erkannt werden sollen (die aufgelisteten sind die aktuell erkannten): +ocr.selectText.1=Wählen Sie die Sprachen aus, die in der PDF-Datei erkannt werden sollen (die aufgelisteten sind die aktuell erkannten): ocr.selectText.2=Textdatei mit OCR-Text neben der OCR-PDF-Datei erstellen -ocr.help=Bitte lesen Sie diese Dokumentation, um zu erfahren, wie Sie dies für andere Sprachen verwenden und/oder nicht in Docker verwenden können -ocr.credit=Dieser Dienst verwendet OCRmyPDF und Tesseract für OCR. +ocr.help=Bitte lesen Sie diese Dokumentation, um zu erfahren, wie Sie dies für andere Sprachen verwenden und/oder nicht in Docker verwenden können +ocr.credit=Dieser Dienst verwendet OCRmyPDF und Tesseract für OCR. ocr.submit=PDF mit OCR verarbeiten extractImages.title=Bilder extrahieren extractImages.header=Bilder extrahieren -extractImages.selectText=Wählen Sie das Bildformat aus, in das extrahierte Bilder konvertiert werden sollen +extractImages.selectText=Wählen Sie das Bildformat aus, in das extrahierte Bilder konvertiert werden sollen extractImages.submit=Extrahieren #File to PDF fileToPDF.title=Datei in PDF fileToPDF.header=Beliebige Dateien in PDF konvertieren -fileToPDF.credit=Dieser Dienst verwendet LibreOffice und Unoconv für die Dateikonvertierung. -fileToPDF.supportedFileTypes=Unterstützte Dateitypen sollten die folgenden enthalten, eine vollständige aktualisierte Liste der unterstützten Formate finden Sie jedoch in der LibreOffice-Dokumentation +fileToPDF.credit=Dieser Dienst verwendet LibreOffice und Unoconv für die Dateikonvertierung. +fileToPDF.supportedFileTypes=Unterstützte Dateitypen sollten die folgenden enthalten, eine vollständige aktualisierte Liste der unterstützten Formate finden Sie jedoch in der LibreOffice-Dokumentation fileToPDF.submit=In PDF konvertieren @@ -120,14 +120,14 @@ fileToPDF.submit=In PDF konvertieren #Add image -addImage.title=Bild hinzufügen -addImage.header=Ein Bild einfügen (Work in progress) -addImage.submit=Bild hinzufügen +addImage.title=Bild hinzufügen +addImage.header=Ein Bild einfügen (Work in progress) +addImage.submit=Bild hinzufügen #compress compress.title=Komprimieren compress.header=PDF komprimieren -compress.credit=Dieser Dienst verwendet OCRmyPDF für die PDF-Komprimierung/-Optimierung. +compress.credit=Dieser Dienst verwendet OCRmyPDF für die PDF-Komprimierung/-Optimierung. compress.selectText.1=Optimierungsstufe: compress.selectText.2=0 (Keine Optimierung) compress.selectText.3=1 (Standard, verlustfreie Optimierung) @@ -139,9 +139,9 @@ compress.submit=Komprimieren #merge -merge.title=Zusammenführen -merge.header=Mehrere PDFs zusammenführen (2+) -merge.submit=Zusammenführen +merge.title=Zusammenführen +merge.header=Mehrere PDFs zusammenführen (2+) +merge.submit=Zusammenführen #pdfOrganiser pdfOrganiser.title=Seiten anordnen @@ -153,12 +153,12 @@ pdfOrganiser.submit=Seiten anordnen pageRemover.title=Seiten entfernen pageRemover.header=PDF Seiten entfernen pageRemover.pagesToDelete=Seiten zu entfernen (geben Sie eine Kommagetrennte Liste der Seitenzahlen an): -pageRemover.submit=Seiten löschen +pageRemover.submit=Seiten löschen #rotate rotate.title=PDF drehen rotate.header=PDF drehen -rotate.selectAngle=Wählen Sie den Winkel (in Vielfachen von 90 Grad): +rotate.selectAngle=Wählen Sie den Winkel (in Vielfachen von 90 Grad): rotate.submit=Drehen @@ -167,8 +167,8 @@ rotate.submit=Drehen #merge split.title=PDF aufteilen split.header=PDF aufteilen -split.desc.1=Die Nummern, die Sie auswählen, sind die Seitenzahlen, an denen Sie aufteilen möchten. -split.desc.2=So würde die Auswahl von 1,3,7-8 ein 10-seitiges Dokument in 6 separate PDFs aufteilen, mit: +split.desc.1=Die Nummern, die Sie auswählen, sind die Seitenzahlen, an denen Sie aufteilen möchten. +split.desc.2=So würde die Auswahl von 1,3,7-8 ein 10-seitiges Dokument in 6 separate PDFs aufteilen, mit: split.desc.3=Dokument #1: Seite 1 split.desc.4=Dokument #2: Seite 2 und 3 split.desc.5=Dokument #3: Seite 4, 5 und 6 @@ -189,97 +189,97 @@ pdfToImage.title=PDF zu Bild pdfToImage.header=PDF zu Bild pdfToImage.selectText=Bildformat pdfToImage.singleOrMultiple=Bildergebnistyp -pdfToImage.single=Einzelnes großes Bild +pdfToImage.single=Einzelnes großes Bild pdfToImage.multi=Mehrere Bilder pdfToImage.colorType=Farbtyp pdfToImage.color=Farbe pdfToImage.grey=Graustufen -pdfToImage.blackwhite=Schwarzweiß (Datenverlust möglich!) +pdfToImage.blackwhite=Schwarzweiß (Datenverlust möglich!) pdfToImage.submit=Umwandeln #addPassword -addPassword.title=Passwort hinzufügen -addPassword.header=Passwort hinzufügen (Verschlüsseln) -addPassword.selectText.1=Das zu verschlüsselnde PDF auswählen +addPassword.title=Passwort hinzufügen +addPassword.header=Passwort hinzufügen (Verschlüsseln) +addPassword.selectText.1=Das zu verschlüsselnde PDF auswählen addPassword.selectText.2=Passwort -addPassword.selectText.3=Länge des Schlüssels -addPassword.selectText.4=Größere Werte sind stärker, aber niedrigere Werte sind besser kompatibel. +addPassword.selectText.3=Länge des Schlüssels +addPassword.selectText.4=Größere Werte sind stärker, aber niedrigere Werte sind besser kompatibel. addPassword.selectText.5=Zu setzende Berechtigungen addPassword.selectText.6=Das zusammensetzen des PDFs verhindern addPassword.selectText.7=Inhaltsextrahierung verhindern addPassword.selectText.8=Inhaltsextrahierung zur Barrierefreiheit verhindern -addPassword.selectText.9=Ausfüllen des Formulars verhindern +addPassword.selectText.9=Ausfüllen des Formulars verhindern addPassword.selectText.10=Modifizierung verhindern -addPassword.selectText.11=Ändern von Kommentaren verhindern +addPassword.selectText.11=Ändern von Kommentaren verhindern addPassword.selectText.12=Drucken verhindern addPassword.selectText.13=Drucken verschiedener Formate verhindern -addPassword.submit=Verschlüsseln +addPassword.submit=Verschlüsseln #watermark -watermark.title=Wasserzeichen hinzufügen -watermark.header=Wasserzeichen hinzufügen -watermark.selectText.1=PDF auswählen, dem ein Wasserzeichen hinzugefügt werden soll: +watermark.title=Wasserzeichen hinzufügen +watermark.header=Wasserzeichen hinzufügen +watermark.selectText.1=PDF auswählen, dem ein Wasserzeichen hinzugefügt werden soll: watermark.selectText.2=Wasserzeichen Text: -watermark.selectText.3=Schriftgröße: +watermark.selectText.3=Schriftgröße: watermark.selectText.4=Drehung (0-360): watermark.selectText.5=breiteSpacer (horizontaler Abstand zwischen den einzelnen Wasserzeichen): -watermark.selectText.6=höheSpacer (vertikaler Abstand zwischen den einzelnen Wasserzeichen): -watermark.submit=Wasserzeichen hinzufügen +watermark.selectText.6=höheSpacer (vertikaler Abstand zwischen den einzelnen Wasserzeichen): +watermark.submit=Wasserzeichen hinzufügen #remove-watermark remove-watermark.title=Wasserzeichen entfernen remove-watermark.header=Wasserzeichen entfernen -remove-watermark.selectText.1=PDF auswählen, um Wasserzeichen zu entfernen von: +remove-watermark.selectText.1=PDF auswählen, um Wasserzeichen zu entfernen von: remove-watermark.selectText.2=Wasserzeichentext: remove-watermark.submit=Wasserzeichen entfernen #Change permissions -permissions.title=Berechtigungen ändern -permissions.header=Berechtigungen ändern -permissions.warning=Achtung: Damit diese Berechtigungen nicht geändert werden können, wird empfohlen, sie über die "Passwort hinzufügen"-Seite mit einem Passwort zu versehen -permissions.selectText.1=Das zu ändernde PDF auswählen +permissions.title=Berechtigungen ändern +permissions.header=Berechtigungen ändern +permissions.warning=Achtung: Damit diese Berechtigungen nicht geändert werden können, wird empfohlen, sie über die "Passwort hinzufügen"-Seite mit einem Passwort zu versehen +permissions.selectText.1=Das zu ändernde PDF auswählen permissions.selectText.2=Zu setzende Berechtigungen permissions.selectText.3=Das zusammensetzen des PDFs verhindern permissions.selectText.4=Inhaltsextrahierung verhindern permissions.selectText.5=Inhaltsextrahierung zur Barrierefreiheit verhindern -permissions.selectText.6=Ausfüllen des Formulars verhindern +permissions.selectText.6=Ausfüllen des Formulars verhindern permissions.selectText.7=Modifizierung verhindern -permissions.selectText.8=Ändern von Kommentaren verhindern +permissions.selectText.8=Ändern von Kommentaren verhindern permissions.selectText.9=Drucken verhindern permissions.selectText.10=Drucken verschiedener Formate verhindern -permissions.submit=Ändern +permissions.submit=Ändern #remove password removePassword.title=Passwort entfernen -removePassword.header=Passwort entfernen (Entschlüsseln) -removePassword.selectText.1=Das zu entschlüsselnde PDF auswählen +removePassword.header=Passwort entfernen (Entschlüsseln) +removePassword.selectText.1=Das zu entschlüsselnde PDF auswählen removePassword.selectText.2=Passwort removePassword.submit=Entfernen -changeMetadata.title=Metadaten ändern -changeMetadata.header=Metadaten ändern -changeMetadata.selectText.1=Bitte bearbeiten Sie die Variablen, die Sie ändern möchten -changeMetadata.selectText.2=Alle Metadaten löschen +changeMetadata.title=Metadaten ändern +changeMetadata.header=Metadaten ändern +changeMetadata.selectText.1=Bitte bearbeiten Sie die Variablen, die Sie ändern möchten +changeMetadata.selectText.2=Alle Metadaten löschen changeMetadata.selectText.3=Benutzerdefinierte Metadaten anzeigen: changeMetadata.author=Autor: changeMetadata.creationDate=Erstellungsdatum (jjjj/MM/tt HH:mm:ss): changeMetadata.creator=Ersteller: -changeMetadata.keywords=Schlüsselwörter: -changeMetadata.modDate=Änderungsdatum (JJJJ/MM/TT HH:mm:ss): +changeMetadata.keywords=Schlüsselwörter: +changeMetadata.modDate=Änderungsdatum (JJJJ/MM/TT HH:mm:ss): changeMetadata.producer=Produzent: changeMetadata.subject=Betreff: changeMetadata.title=Titel: changeMetadata.trapped=Gefangen: changeMetadata.selectText.4=Andere Metadaten: -changeMetadata.selectText.5=Benutzerdefinierten Metadateneintrag hinzufügen -changeMetadata.submit=Ändern +changeMetadata.selectText.5=Benutzerdefinierten Metadateneintrag hinzufügen +changeMetadata.submit=Ändern xlsToPdf.title=Excel in PDF xlsToPdf.header=Excel in PDF -xlsToPdf.selectText.1=XLS- oder XLSX-Excel-Tabelle zum Konvertieren auswählen +xlsToPdf.selectText.1=XLS- oder XLSX-Excel-Tabelle zum Konvertieren auswählen xlsToPdf.convert=konvertieren diff --git a/src/main/resources/messages_en_GB.properties b/src/main/resources/messages_en_GB.properties index 1214ab33a..0e9ddd235 100644 --- a/src/main/resources/messages_en_GB.properties +++ b/src/main/resources/messages_en_GB.properties @@ -4,10 +4,10 @@ # the direction that the language is written (ltr = left to right, rtl = right to left) language.direction=ltr -pdfPrompt=Choose PDF -multiPdfPrompt=Choose PDFs (2+) +pdfPrompt=Select PDF(s) +multiPdfPrompt=Select PDFs (2+) multiPdfDropPrompt=Select (or drag & drop) all PDFs you require -imgPrompt=Choose Image +imgPrompt=Select Image(s) genericSubmit=Submit processTimeWarning=Warning: This process can take up to a minute depending on file-size pageOrderPrompt=Page Order (Enter a comma-separated list of page numbers) : @@ -91,7 +91,7 @@ settings.downloadOption.title=Choose download option (For single file non zip do settings.downloadOption.1=Open in same window settings.downloadOption.2=Open in new window settings.downloadOption.3=Download file -settings.zip=Zip multi-download files +settings.zipThreshold=Zip files when the number of downloaded files exceeds #OCR ocr.title=OCR diff --git a/src/main/resources/messages_en_US.properties b/src/main/resources/messages_en_US.properties index 77a765145..54f54505b 100644 --- a/src/main/resources/messages_en_US.properties +++ b/src/main/resources/messages_en_US.properties @@ -4,10 +4,10 @@ # the direction that the language is written (ltr = left to right, rtl = right to left) language.direction=ltr -pdfPrompt=Choose PDF -multiPdfPrompt=Choose PDFs (2+) +pdfPrompt=Select PDF(s) +multiPdfPrompt=Select PDFs (2+) multiPdfDropPrompt=Select (or drag & drop) all PDFs you require -imgPrompt=Choose Image +imgPrompt=Select Image(s) genericSubmit=Submit processTimeWarning=Warning: This process can take up to a minute depending on file-size pageOrderPrompt=Page Order (Enter a comma-separated list of page numbers) : @@ -91,7 +91,7 @@ settings.downloadOption.title=Choose download option (For single file non zip do settings.downloadOption.1=Open in same window settings.downloadOption.2=Open in new window settings.downloadOption.3=Download file -settings.zip=Zip multi-download files +settings.zipThreshold=Zip files when the number of downloaded files exceeds #OCR ocr.title=OCR diff --git a/src/main/resources/messages_fr_FR.properties b/src/main/resources/messages_fr_FR.properties index b26d72290..06c931f71 100644 --- a/src/main/resources/messages_fr_FR.properties +++ b/src/main/resources/messages_fr_FR.properties @@ -96,7 +96,7 @@ settings.downloadOption.title=Choisissez l\u2019option de t settings.downloadOption.1=Ouvrir dans la même fenêtre settings.downloadOption.2=Ouvrir dans une nouvelle fenêtre settings.downloadOption.3=Fichier téléchargé -settings.zip=Fichiers multi-téléchargements Zip +settings.zipThreshold=Zip les fichiers lorsque le nombre de fichiers téléchargés dépasse #OCR diff --git a/src/main/resources/templates/add-image.html b/src/main/resources/templates/add-image.html index 96662487d..f6b67e5f9 100644 --- a/src/main/resources/templates/add-image.html +++ b/src/main/resources/templates/add-image.html @@ -15,9 +15,9 @@

-
+
- +
diff --git a/src/main/resources/templates/compress-pdf.html b/src/main/resources/templates/compress-pdf.html index ad1b4eb9a..64e1c6e80 100644 --- a/src/main/resources/templates/compress-pdf.html +++ b/src/main/resources/templates/compress-pdf.html @@ -15,7 +15,7 @@

-
+
- + + + +
+ +
+ +
+
+ + +
+
+ +
+ + +
+

- + +
diff --git a/src/main/resources/templates/convert/pdf-to-img.html b/src/main/resources/templates/convert/pdf-to-img.html index bfc70fc0c..2b5cf1997 100644 --- a/src/main/resources/templates/convert/pdf-to-img.html +++ b/src/main/resources/templates/convert/pdf-to-img.html @@ -16,7 +16,7 @@

-
+
- - - - - - - -
-
-
- -
- - - - \ No newline at end of file diff --git a/src/main/resources/templates/extract-images.html b/src/main/resources/templates/extract-images.html index 262a1f88e..f7592638d 100644 --- a/src/main/resources/templates/extract-images.html +++ b/src/main/resources/templates/extract-images.html @@ -15,7 +15,7 @@

-
+
+
@@ -90,7 +91,9 @@ function toggleDarkMode() { event.preventDefault(); // Prevent the default form handling behavior /* Check if ${multiple} is false */ var multiple = [[${multiple}]] || false; - if (!multiple && files.length > 1) { + var override = $('#override').val() || ''; + console.log("override=" + override) + if (override === 'multi' || (!multiple && files.length > 1) && override !== 'single' ) { console.log("multi parallel download") submitMultiPdfForm(event,url); } else { @@ -208,8 +211,9 @@ function toggleDarkMode() { progressBar.attr('aria-valuenow', 0); progressBar.attr('aria-valuemax', files.length); - // Check the flag in localStorage - const zipFiles = localStorage.getItem('zipParallelFiles') === 'true'; + // Check the flag in localStorage, default to 4 + const zipThreshold = parseInt(localStorage.getItem('zipThreshold'), 10) || 4; + const zipFiles = files.length > zipThreshold; // Initialize JSZip instance if needed let jszip = null; @@ -355,6 +359,7 @@ function toggleDarkMode() { fileNames.forEach(fileName => { selectedFilesContainer.append("
" + fileName + "
"); }); + console.log("fileNames.length=" + fileNames.length) if (fileNames.length === 1) { $(inputElement).siblings(".custom-file-label").addClass("selected").html(fileNames[0]); } else if (fileNames.length > 1) { diff --git a/src/main/resources/templates/fragments/navbar.html b/src/main/resources/templates/fragments/navbar.html index 1df0cc43f..c6f953728 100644 --- a/src/main/resources/templates/fragments/navbar.html +++ b/src/main/resources/templates/fragments/navbar.html @@ -206,25 +206,24 @@ function compareVersions(version1, version2) {