Skip to content

Commit

Permalink
Merge pull request #14 from jwblangley/image-compression
Browse files Browse the repository at this point in the history
Image compression
  • Loading branch information
jwblangley authored Mar 18, 2020
2 parents 348c76c + bc385fc commit 8776df4
Show file tree
Hide file tree
Showing 10 changed files with 672 additions and 3 deletions.
15 changes: 12 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Backend

## Configuration

Edit the file `backend/run.sh` to change the data directory location - this is where all uploaded media content will be stored. By default this is the folder `.plo` in the home directory

If required edit the port number in `run.sh`. This should match the port number entered in the frontend config.
If required edit the port number in `run.sh`; the default is 8008. This should match the port number entered in the frontend config.

* Requires `ffmpeg` and `mongo` to be installed.
* Ensure that the mongo data store path is set. This can be done with `mongod --dbpath <location>`. It is recommended to use `/data/db`.
Expand All @@ -21,13 +23,20 @@ Saves all stored content to `export.zip`
Restores all content from a previous export
Usage: `./plo-import export.zip`

### `plo-compress-existing`
For existing applications prior to the introduction of image compression.
Compresses existing images in the application to be in line with newer versions.
Usage: `./plo-import export.zip`


# Frontend

## Configuration
Before running this project, create a `.env` file in the frontend directory with the contents:

```
REACT_APP_BACKEND_PORT_BASE=<backend port number>
REACT_APP_SELF_BACKEND=<true|false>
REACT_APP_BACKEND_PORT_BASE=<backend port number>
REACT_APP_SELF_BACKEND=<true|false>
```

* The default backend port number is 8008 (N.B: The backend actually uses two successive ports starting with the given port number).
Expand Down
62 changes: 62 additions & 0 deletions backend/imageProcessing.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
const jimp = require('jimp')

// 16 MP
const MAX_SIZE = 16 * 1000 * 1000
// 80% Quality
const QUALITY = 75

const EPSILON = 0.01

function processImage(input, cb, overwrite = true) {
jimp.read(input, (err, img) => {
if (err) {
cb(err)
return
}
const split = input.match(/(.*)\.(.*)/)
const filename = split[1]
const fileExt = split[2]

const size = img.bitmap.width * img.bitmap.height

if (size < EPSILON * MAX_SIZE) {
return
}

const factor = Math.sqrt(MAX_SIZE / size)
img
.scale(factor)
.quality(QUALITY)
.write(filename + (overwrite ? '' : '-processed') + '.' + fileExt)
if (cb) {
cb()
}
})
}

async function processImageSync(input, overwrite = true) {
await jimp.read(input)
.then(img => {
const split = input.match(/(.*)\.(.*)/)
const filename = split[1]
const fileExt = split[2]

const size = img.bitmap.width * img.bitmap.height

if (size < EPSILON * MAX_SIZE) {
return
}

const factor = Math.sqrt(MAX_SIZE / size)
return img
.scale(factor)
.quality(QUALITY)
.write(filename + (overwrite ? '' : '-processed') + '.' + fileExt)
})
.catch(err => console.error(err))
}

module.exports = {
processImage,
processImageSync
}
13 changes: 13 additions & 0 deletions backend/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const fs = require('fs')
const multer = require('multer')

const mongoManager = require('./mongoManager.js')
const imageProcessing = require('./imageProcessing.js')

const app = express()
const API_PORT = process.env.PORT_BASE
Expand Down Expand Up @@ -96,6 +97,8 @@ app.post('/:username/addUserMedia', (req, res) => {
// Ensure to wait for addUserMedia to finish
await mongoManager.addUserMedia(username, req.files, DATA_DIRECTORY)

await compressImages(req.files)

return res.send("Successfully uploaded " + req.files.length + " "
+ (req.files.length > 1 ? "files" : "file"))
}
Expand All @@ -116,6 +119,8 @@ app.post('/:username/addUserGallery', (req, res) => {
// Ensure to wait for addUserMedia to finish
await mongoManager.addUserGallery(username, req.files, DATA_DIRECTORY)

await compressImages(req.files)

return res.send("Successfully uploaded " + req.files.length + " "
+ (req.files.length > 1 ? "files" : "file") + " to gallery")
}
Expand All @@ -124,6 +129,14 @@ app.post('/:username/addUserGallery', (req, res) => {

/*----------------------------------------------------------------------------*/

async function compressImages(files) {
files = files.map(f => DATA_DIRECTORY + "/" + f.filename)
for (var i = 0; i < files.length; i++) {
const file = files[i]
await imageProcessing.processImageSync(file)
}
}

// Delete files that are no longer being referenced
async function garbageCollect() {
const allMedia = await mongoManager.getAllMedia()
Expand Down
Loading

0 comments on commit 8776df4

Please sign in to comment.