Skip to content

Commit

Permalink
F!!: init version
Browse files Browse the repository at this point in the history
  • Loading branch information
lolobosse committed Jul 31, 2022
1 parent c91fe09 commit 0f3d7e1
Show file tree
Hide file tree
Showing 15 changed files with 8,988 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
@@ -0,0 +1,2 @@
node_modules
.idea
23 changes: 23 additions & 0 deletions Readme.md
@@ -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
13 changes: 13 additions & 0 deletions index.html
@@ -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>
21 changes: 21 additions & 0 deletions package.json
@@ -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"
}
}
1 change: 1 addition & 0 deletions public/pdf-file.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
61 changes: 61 additions & 0 deletions src/App.css
@@ -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;
}
100 changes: 100 additions & 0 deletions src/App.jsx
@@ -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
1 change: 1 addition & 0 deletions src/assets/react.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
70 changes: 70 additions & 0 deletions src/index.css
@@ -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;
}
}

0 comments on commit 0f3d7e1

Please sign in to comment.