Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
8,988 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
node_modules | ||
.idea |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Ghostscript-pdf-compress.wasm | ||
|
||
## Context | ||
This project is a demo of another usage of the `gs.wasm` that [@ochachacha](https://github.com/ochachacha) compiled. It takes any PDF and compress it via ghostscript. | ||
|
||
The applied command is: | ||
|
||
``` | ||
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook -dNOPAUSE -dQUIET -dBATCH -sOutputFile=output.pdf input.pdf | ||
``` | ||
|
||
## Run the project | ||
|
||
To run the project, simply do the following steps | ||
|
||
```bash | ||
git clone git@github.com:laurentmmeyer/ghostscript-pdf-compress.wasm.git | ||
cd ghostscript-pdf-compress.wasm | ||
yarn | ||
yarn dev | ||
``` | ||
|
||
## Demo |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<link rel="icon" type="image/svg+xml" href="/pdf-file.svg" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>Vite + React</title> | ||
</head> | ||
<body> | ||
<div id="root"></div> | ||
<script type="module" src="/src/main.jsx"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{ | ||
"name": "pdf-compress.wasm", | ||
"private": true, | ||
"version": "0.0.0", | ||
"type": "module", | ||
"scripts": { | ||
"dev": "vite", | ||
"build": "vite build", | ||
"preview": "vite preview" | ||
}, | ||
"dependencies": { | ||
"react": "^18.2.0", | ||
"react-dom": "^18.2.0" | ||
}, | ||
"devDependencies": { | ||
"@types/react": "^18.0.15", | ||
"@types/react-dom": "^18.0.6", | ||
"@vitejs/plugin-react": "^2.0.0", | ||
"vite": "^3.0.0" | ||
} | ||
} |
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
#root { | ||
max-width: 1280px; | ||
margin: 0 auto; | ||
padding: 2rem; | ||
text-align: center; | ||
} | ||
|
||
form { | ||
margin:0 auto; | ||
padding:20px; | ||
width:400px; | ||
height:auto; | ||
overflow:hidden; | ||
background:#FFFFFF; | ||
border-radius:3px; | ||
} | ||
|
||
label { | ||
margin:0; | ||
padding:10px; | ||
width:auto; | ||
max-width:300px; | ||
height:auto; | ||
background-color:#929292; | ||
border:none; | ||
color:#fff; | ||
cursor:pointer; | ||
text-align:center; | ||
border-radius:5px; | ||
-webkit-border-radius:5px; | ||
-webkit-transition:0.2s ease all; | ||
-moz-transition:0.2s ease all; | ||
-ms-transition:0.2s ease all; | ||
-o-transition:0.2s ease all; | ||
transition:0.2s ease all; | ||
} | ||
|
||
[type=file]{ | ||
display:none; | ||
} | ||
|
||
[type=submit] { | ||
margin-top: 30px; | ||
background-color: #65b453; | ||
border:none; | ||
color:#fff; | ||
cursor: pointer; | ||
padding:10px; | ||
font-size: large; | ||
border-radius:5px; | ||
-webkit-border-radius:5px; | ||
-webkit-transition:0.2s ease all; | ||
-moz-transition:0.2s ease all; | ||
-ms-transition:0.2s ease all; | ||
-o-transition:0.2s ease all; | ||
transition:0.2s ease all; | ||
} | ||
|
||
label:hover { | ||
background:#ADADAD; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
import {useState} from 'react' | ||
import './App.css' | ||
import {_GSPS2PDF} from "./lib/background.js"; | ||
|
||
|
||
function loadPDFData(response, filename) { | ||
const xhr = new XMLHttpRequest(); | ||
xhr.open("GET", response.pdfDataURL); | ||
xhr.responseType = "arraybuffer"; | ||
xhr.onload = function () { | ||
window.URL.revokeObjectURL(response.pdfDataURL); | ||
const blob = new Blob([xhr.response], {type: "application/pdf"}); | ||
const pdfURL = window.URL.createObjectURL(blob); | ||
document.title = filename; | ||
const link = document.createElement("a"); | ||
link.href = pdfURL; | ||
link.download = filename; | ||
document.body.appendChild(link); | ||
link.click(); | ||
setTimeout(function () { | ||
document.body.removeChild(link); | ||
window.URL.revokeObjectURL(pdfURL); | ||
// TODO: Hacky but this is not working twice, need to inspect the problem closer | ||
location.reload(); | ||
}, 0); | ||
}; | ||
xhr.send(); | ||
} | ||
|
||
|
||
function App() { | ||
const [state, setState] = useState("init") | ||
const [file, setFile] = useState(undefined) | ||
|
||
function compressPDF(pdf, filename) { | ||
const dataObject = {psDataURL: pdf} | ||
_GSPS2PDF(dataObject, | ||
(element) => { | ||
console.log(element); | ||
setState("success") | ||
loadPDFData(element, filename); | ||
}, | ||
(...args) => console.log("Progress:", JSON.stringify(args)), | ||
(element) => console.log("Status Update:", JSON.stringify(element))) | ||
} | ||
|
||
const changeHandler = (event) => { | ||
const file = event.target.files[0] | ||
const url = window.URL.createObjectURL(file); | ||
setFile({filename: file.name, url}) | ||
setState('selected') | ||
}; | ||
|
||
const onSubmit = (event) => { | ||
event.preventDefault(); | ||
const {filename, url} = file; | ||
compressPDF(url, filename) | ||
setState("loading") | ||
return false; | ||
} | ||
|
||
return ( | ||
<> | ||
<h1>Free Browser side PDF-Compressor</h1> | ||
<p> | ||
The best tool I know to compress PDF is <a target={"_blank"} | ||
href={"https://ghostscript.com/"}>Ghostscript</a> but this | ||
was | ||
not running into the browser. Until <a target={"_blank"} | ||
href={"https://github.com/ochachacha/ps-wasm"}>Ochachacha</a> ported | ||
the lib in <a target={"_blank"} | ||
href={"https://webassembly.org/"}>Webassembly</a>.</p> | ||
<p> | ||
Based on his amazing work, I built this <a | ||
href={"https://github.com/laurentmmeyer/ghostscript-pdf-compress.wasm"} target={"_blank"}>demo</a> together. | ||
It's running on Vite and React. It imports the WASM on the fly when you want compress a PDF. | ||
</p> | ||
<p> | ||
Be aware that the Webassembly binary is weighting <b>18MB</b>. | ||
</p> | ||
<p><i>Secure and private by design: the data never leave your computer.</i></p> | ||
{state !== "loading" && | ||
<form onSubmit={onSubmit}> | ||
<input type="file" accept={"application/pdf"} name="file" | ||
onChange={changeHandler} id={"file"}/> | ||
<label htmlFor={"file"}>{!file || !file.filename ? `Choose PDF to compress` : file.filename}</label> | ||
{state === 'selected' && | ||
<input className={"button"} type="submit" value={"🚀 Compress this PDF in the browser! 🚀"}/>} | ||
</form>} | ||
{state === "loading" && "Loading...."} | ||
|
||
<p> | ||
Everything is open-source and you can contribute <a | ||
href={"https://github.com/laurentmmeyer/ghostscript-pdf-compress.wasm"} target={"_blank"}>here</a>. | ||
</p> | ||
</> | ||
) | ||
} | ||
|
||
export default App |
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
:root { | ||
font-family: Inter, Avenir, Helvetica, Arial, sans-serif; | ||
font-size: 16px; | ||
line-height: 24px; | ||
font-weight: 400; | ||
|
||
color-scheme: light dark; | ||
color: rgba(255, 255, 255, 0.87); | ||
background-color: #242424; | ||
|
||
font-synthesis: none; | ||
text-rendering: optimizeLegibility; | ||
-webkit-font-smoothing: antialiased; | ||
-moz-osx-font-smoothing: grayscale; | ||
-webkit-text-size-adjust: 100%; | ||
} | ||
|
||
a { | ||
font-weight: 500; | ||
color: #646cff; | ||
text-decoration: inherit; | ||
} | ||
a:hover { | ||
color: #535bf2; | ||
} | ||
|
||
body { | ||
margin: 0; | ||
display: flex; | ||
place-items: center; | ||
min-width: 320px; | ||
min-height: 100vh; | ||
} | ||
|
||
h1 { | ||
font-size: 3.2em; | ||
line-height: 1.1; | ||
} | ||
|
||
button { | ||
border-radius: 8px; | ||
border: 1px solid transparent; | ||
padding: 0.6em 1.2em; | ||
font-size: 1em; | ||
font-weight: 500; | ||
font-family: inherit; | ||
background-color: #1a1a1a; | ||
cursor: pointer; | ||
transition: border-color 0.25s; | ||
} | ||
button:hover { | ||
border-color: #646cff; | ||
} | ||
button:focus, | ||
button:focus-visible { | ||
outline: 4px auto -webkit-focus-ring-color; | ||
} | ||
|
||
@media (prefers-color-scheme: light) { | ||
:root { | ||
color: #213547; | ||
background-color: #ffffff; | ||
} | ||
a:hover { | ||
color: #747bff; | ||
} | ||
button { | ||
background-color: #f9f9f9; | ||
} | ||
} |
Oops, something went wrong.