mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2024-12-21 19:08:24 +01:00
commit
909c9ed4d9
@ -124,6 +124,7 @@ public class EndpointConfiguration {
|
|||||||
addEndpointToGroup("Other", "flatten");
|
addEndpointToGroup("Other", "flatten");
|
||||||
addEndpointToGroup("Other", "repair");
|
addEndpointToGroup("Other", "repair");
|
||||||
addEndpointToGroup("Other", "remove-blanks");
|
addEndpointToGroup("Other", "remove-blanks");
|
||||||
|
addEndpointToGroup("Other", "remove-annotations");
|
||||||
addEndpointToGroup("Other", "compare");
|
addEndpointToGroup("Other", "compare");
|
||||||
addEndpointToGroup("Other", "add-page-numbers");
|
addEndpointToGroup("Other", "add-page-numbers");
|
||||||
addEndpointToGroup("Other", "auto-rename");
|
addEndpointToGroup("Other", "auto-rename");
|
||||||
|
@ -127,6 +127,12 @@ public class OtherWebController {
|
|||||||
return "misc/remove-blanks";
|
return "misc/remove-blanks";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/remove-annotations")
|
||||||
|
@Hidden
|
||||||
|
public String removeAnnotationsForm(Model model) {
|
||||||
|
model.addAttribute("currentPage", "remove-annotations");
|
||||||
|
return "misc/remove-annotations";
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/auto-crop")
|
@GetMapping("/auto-crop")
|
||||||
@Hidden
|
@Hidden
|
||||||
|
@ -255,6 +255,10 @@ home.removeBlanks.title=Remove Blank pages
|
|||||||
home.removeBlanks.desc=Detects and removes blank pages from a document
|
home.removeBlanks.desc=Detects and removes blank pages from a document
|
||||||
removeBlanks.tags=cleanup,streamline,non-content,organize
|
removeBlanks.tags=cleanup,streamline,non-content,organize
|
||||||
|
|
||||||
|
home.removeAnnotations.title=Remove Annotations
|
||||||
|
home.removeAnnotations.desc=Removes all comments/annotations from a PDF
|
||||||
|
removeAnnotations.tags=comments,highlight,notes,markup,remove
|
||||||
|
|
||||||
home.compare.title=Compare
|
home.compare.title=Compare
|
||||||
home.compare.desc=Compares and shows the differences between 2 PDF Documents
|
home.compare.desc=Compares and shows the differences between 2 PDF Documents
|
||||||
compare.tags=differentiate,contrast,changes,analysis
|
compare.tags=differentiate,contrast,changes,analysis
|
||||||
@ -539,6 +543,12 @@ removeBlanks.whitePercentDesc=Percent of page that must be 'white' pixels to be
|
|||||||
removeBlanks.submit=Remove Blanks
|
removeBlanks.submit=Remove Blanks
|
||||||
|
|
||||||
|
|
||||||
|
#removeAnnotations
|
||||||
|
removeAnnotations.title=Remove Annotations
|
||||||
|
removeAnnotations.header=Remove Annotations
|
||||||
|
removeAnnotations.submit=Remove
|
||||||
|
|
||||||
|
|
||||||
#compare
|
#compare
|
||||||
compare.title=Compare
|
compare.title=Compare
|
||||||
compare.header=Compare PDFs
|
compare.header=Compare PDFs
|
||||||
|
@ -255,6 +255,10 @@ home.removeBlanks.title=Remove Blank pages
|
|||||||
home.removeBlanks.desc=Detects and removes blank pages from a document
|
home.removeBlanks.desc=Detects and removes blank pages from a document
|
||||||
removeBlanks.tags=cleanup,streamline,non-content,organize
|
removeBlanks.tags=cleanup,streamline,non-content,organize
|
||||||
|
|
||||||
|
home.removeAnnotations.title=Remove Annotations
|
||||||
|
home.removeAnnotations.desc=Removes all comments/annotations from a PDF
|
||||||
|
removeAnnotations.tags=comments,highlight,notes,markup,remove
|
||||||
|
|
||||||
home.compare.title=Compare
|
home.compare.title=Compare
|
||||||
home.compare.desc=Compares and shows the differences between 2 PDF Documents
|
home.compare.desc=Compares and shows the differences between 2 PDF Documents
|
||||||
compare.tags=differentiate,contrast,changes,analysis
|
compare.tags=differentiate,contrast,changes,analysis
|
||||||
@ -539,6 +543,12 @@ removeBlanks.whitePercentDesc=Percent of page that must be 'white' pixels to be
|
|||||||
removeBlanks.submit=Remove Blanks
|
removeBlanks.submit=Remove Blanks
|
||||||
|
|
||||||
|
|
||||||
|
#removeAnnotations
|
||||||
|
removeAnnotations.title=Remove Annotations
|
||||||
|
removeAnnotations.header=Remove Annotations
|
||||||
|
removeAnnotations.submit=Remove
|
||||||
|
|
||||||
|
|
||||||
#compare
|
#compare
|
||||||
compare.title=Compare
|
compare.title=Compare
|
||||||
compare.header=Compare PDFs
|
compare.header=Compare PDFs
|
||||||
|
6
src/main/resources/static/images/no-chat.svg
Normal file
6
src/main/resources/static/images/no-chat.svg
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<svg width="16" height="16" fill="currentColor" class="bi bi-chat-left-text" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M14 1a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1H4.414A2 2 0 0 0 3 11.586l-2 2V2a1 1 0 0 1 1-1zM2 0a2 2 0 0 0-2 2v12.793a.5.5 0 0 0 .854.353l2.853-2.853A1 1 0 0 1 4.414 12H14a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2z" style="fill: rgb(0, 0, 0);"/>
|
||||||
|
<path d="M3 3.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5M3 6a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9A.5.5 0 0 1 3 6m0 2.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5" style="fill: rgb(0, 0, 0);"/>
|
||||||
|
<path d="M 0.125 0.178 C 0.312 -0.024 0.636 -0.043 0.831 0.152 L 15.771 15.1 C 16.242 15.571 15.561 16.304 15.09 15.832 L 0.151 0.885 C -0.045 0.69 -0.063 0.381 0.125 0.178 Z" id="path937" style="fill: rgb(0, 0, 0);"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 853 B |
@ -107,7 +107,7 @@
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="nav-item nav-item-separator"></li>
|
<li class="nav-item nav-item-separator"></li>
|
||||||
<li class="nav-item dropdown" th:classappend="${currentPage}=='sign' OR ${currentPage}=='repair' OR ${currentPage}=='compare' OR ${currentPage}=='show-javascript' OR ${currentPage}=='flatten' OR ${currentPage}=='remove-blanks' OR ${currentPage}=='extract-image-scans' OR ${currentPage}=='change-metadata' OR ${currentPage}=='add-image' OR ${currentPage}=='ocr-pdf' OR ${currentPage}=='change-permissions' OR ${currentPage}=='extract-images' OR ${currentPage}=='compress-pdf' OR ${currentPage}=='add-page-numbers' OR ${currentPage}=='auto-rename' OR ${currentPage}=='get-info-on-pdf' ? 'active' : ''">
|
<li class="nav-item dropdown" th:classappend="${currentPage}=='sign' OR ${currentPage}=='repair' OR ${currentPage}=='compare' OR ${currentPage}=='show-javascript' OR ${currentPage}=='flatten' OR ${currentPage}=='remove-blanks' OR ${currentPage}=='remove-annotations' OR ${currentPage}=='extract-image-scans' OR ${currentPage}=='change-metadata' OR ${currentPage}=='add-image' OR ${currentPage}=='ocr-pdf' OR ${currentPage}=='change-permissions' OR ${currentPage}=='extract-images' OR ${currentPage}=='compress-pdf' OR ${currentPage}=='add-page-numbers' OR ${currentPage}=='auto-rename' OR ${currentPage}=='get-info-on-pdf' ? 'active' : ''">
|
||||||
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
<img class="icon" src="images/card-list.svg" alt="icon" style="width: 16px; height: 16px; vertical-align: middle;">
|
<img class="icon" src="images/card-list.svg" alt="icon" style="width: 16px; height: 16px; vertical-align: middle;">
|
||||||
<span class="icon-text" th:text="#{navbar.other}"></span>
|
<span class="icon-text" th:text="#{navbar.other}"></span>
|
||||||
@ -125,6 +125,7 @@
|
|||||||
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('flatten', 'images/flatten.svg', 'home.flatten.title', 'home.flatten.desc', 'flatten.tags')}"></div>
|
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('flatten', 'images/flatten.svg', 'home.flatten.title', 'home.flatten.desc', 'flatten.tags')}"></div>
|
||||||
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('repair', 'images/wrench.svg', 'home.repair.title', 'home.repair.desc', 'repair.tags')}"></div>
|
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('repair', 'images/wrench.svg', 'home.repair.title', 'home.repair.desc', 'repair.tags')}"></div>
|
||||||
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('remove-blanks', 'images/blank-file.svg', 'home.removeBlanks.title', 'home.removeBlanks.desc', 'removeBlanks.tags')}"></div>
|
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('remove-blanks', 'images/blank-file.svg', 'home.removeBlanks.title', 'home.removeBlanks.desc', 'removeBlanks.tags')}"></div>
|
||||||
|
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('remove-annotations', 'images/no-chat.svg', 'home.removeAnnotations.title', 'home.removeAnnotations.desc', 'removeAnnotations.tags')}"></div>
|
||||||
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('compare', 'images/scales.svg', 'home.compare.title', 'home.compare.desc', 'compare.tags')}"></div>
|
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('compare', 'images/scales.svg', 'home.compare.title', 'home.compare.desc', 'compare.tags')}"></div>
|
||||||
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('add-page-numbers', 'images/add-page-numbers.svg', 'home.add-page-numbers.title', 'home.add-page-numbers.desc', 'add-page-numbers.tags')}"></div>
|
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('add-page-numbers', 'images/add-page-numbers.svg', 'home.add-page-numbers.title', 'home.add-page-numbers.desc', 'add-page-numbers.tags')}"></div>
|
||||||
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('auto-rename', 'images/fonts.svg', 'home.auto-rename.title', 'home.auto-rename.desc', 'auto-rename.tags')}"></div>
|
<div th:replace="~{fragments/navbarEntry :: navbarEntry ('auto-rename', 'images/fonts.svg', 'home.auto-rename.title', 'home.auto-rename.desc', 'auto-rename.tags')}"></div>
|
||||||
|
@ -73,6 +73,7 @@
|
|||||||
|
|
||||||
<div th:replace="~{fragments/card :: card(id='repair', cardTitle=#{home.repair.title}, cardText=#{home.repair.desc}, cardLink='repair', svgPath='images/wrench.svg')}"></div>
|
<div th:replace="~{fragments/card :: card(id='repair', cardTitle=#{home.repair.title}, cardText=#{home.repair.desc}, cardLink='repair', svgPath='images/wrench.svg')}"></div>
|
||||||
<div th:replace="~{fragments/card :: card(id='remove-blanks', cardTitle=#{home.removeBlanks.title}, cardText=#{home.removeBlanks.desc}, cardLink='remove-blanks', svgPath='images/blank-file.svg')}"></div>
|
<div th:replace="~{fragments/card :: card(id='remove-blanks', cardTitle=#{home.removeBlanks.title}, cardText=#{home.removeBlanks.desc}, cardLink='remove-blanks', svgPath='images/blank-file.svg')}"></div>
|
||||||
|
<div th:replace="~{fragments/card :: card(id='remove-annotations', cardTitle=#{home.removeAnnotations.title}, cardText=#{home.removeAnnotations.desc}, cardLink='remove-annotations', svgPath='images/no-chat.svg')}"></div>
|
||||||
<div th:replace="~{fragments/card :: card(id='compare', cardTitle=#{home.compare.title}, cardText=#{home.compare.desc}, cardLink='compare', svgPath='images/scales.svg')}"></div>
|
<div th:replace="~{fragments/card :: card(id='compare', cardTitle=#{home.compare.title}, cardText=#{home.compare.desc}, cardLink='compare', svgPath='images/scales.svg')}"></div>
|
||||||
|
|
||||||
<div th:replace="~{fragments/card :: card(id='cert-sign', cardTitle=#{home.certSign.title}, cardText=#{home.certSign.desc}, cardLink='cert-sign', svgPath='images/award.svg')}"></div>
|
<div th:replace="~{fragments/card :: card(id='cert-sign', cardTitle=#{home.certSign.title}, cardText=#{home.certSign.desc}, cardLink='cert-sign', svgPath='images/award.svg')}"></div>
|
||||||
|
64
src/main/resources/templates/misc/remove-annotations.html
Normal file
64
src/main/resources/templates/misc/remove-annotations.html
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<th:block th:insert="~{fragments/common :: head(title=#{removeAnnotations.title})}"></th:block>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="page-container">
|
||||||
|
<div id="content-wrap">
|
||||||
|
<div th:insert="~{fragments/navbar.html :: navbar}"></div>
|
||||||
|
<br> <br>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<h2 th:text="#{removeAnnotations.header}"></h2>
|
||||||
|
<form id="pdfForm" class="mb-3">
|
||||||
|
<div class="custom-file">
|
||||||
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf', remoteCall='false')}"></div>
|
||||||
|
</div>
|
||||||
|
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{removeAnnotations.submit}"></button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div th:insert="~{fragments/footer.html :: footer}"></div>
|
||||||
|
</div>
|
||||||
|
<script src="js/local-pdf-input-download.js"></script>
|
||||||
|
<script>
|
||||||
|
document.getElementById('pdfForm').addEventListener('submit', async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const { PDFDocument } = PDFLib;
|
||||||
|
|
||||||
|
const processFile = async (file) => {
|
||||||
|
const origFileUrl = URL.createObjectURL(file);
|
||||||
|
const formPdfBytes = await fetch(origFileUrl).then(res => res.arrayBuffer());
|
||||||
|
const pdfDoc = await PDFDocument.load(formPdfBytes, { ignoreEncryption: true });
|
||||||
|
|
||||||
|
const pages = pdfDoc.getPages();
|
||||||
|
|
||||||
|
for (let i = 0; i < pages.length; ++i) {
|
||||||
|
const page = pages[i];
|
||||||
|
const annotations = page.node.Annots();
|
||||||
|
if (!annotations) continue;
|
||||||
|
const ctx = annotations.context;
|
||||||
|
|
||||||
|
for (let j = 0; j < annotations.size(); ++j) {
|
||||||
|
const annotation = annotations.get(j);
|
||||||
|
ctx.delete(annotation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const pdfBytes = await pdfDoc.save();
|
||||||
|
const pdfBlob = new Blob([pdfBytes], { type: 'application/pdf' });
|
||||||
|
const fileName = (file.name ? file.name.replace('.pdf', '') : 'pdf') + '_removed_annotations.pdf';
|
||||||
|
|
||||||
|
return { processedData: pdfBlob, fileName };
|
||||||
|
};
|
||||||
|
|
||||||
|
await downloadFilesWithCallback(processFile);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user