Skip to content

Instantly share code, notes, and snippets.

@taylorstine
Last active March 11, 2017 15:24
Show Gist options
  • Save taylorstine/f413a5ba2e60021edf9ca7769a7f59c7 to your computer and use it in GitHub Desktop.
Save taylorstine/f413a5ba2e60021edf9ca7769a7f59c7 to your computer and use it in GitHub Desktop.
Middleware to resize the image
import urlJoin from "url-join";
import R from "ramda";
import request from "request";
import sharp from "sharp";
export const containMiddleware = (req, res, next) => {
//Use pipe to pass in the results from one function to the next
R.pipe(makeResizer('contain'), requestImage(req, res, next))(req, res, next);
};
export const coverMiddleware = (req, res, next) => {
//Use pipe to pass in the results from one function to the next
R.pipe(makeResizer('cover'), requestImage(req, res, next))(req, res, next);
};
const requestImage = (req, res, next)=>(resizer)=>{
const {image, imageHost} = res.stash.params;
const url: string = urlJoin(`http${req.secure ? "s": ""}://`, imageHost, image);
const stream = request(url);
//We want to know when we have a 404 error
stream.on('response', resp=> {
if (resp.statusCode >= 400) {
next(new Error( "Could not access image"))
} else {
//set the content type, if the original image had one
res.set('Content-Type', resp.headers['content-type']);
stream.pipe(resizer).pipe(res);
}
});
};
/**
* Creates a resizer that accepts an input stream and can pipe out an output stream
* @param type - must be one of "contain" or "cover"
*/
const makeResizer = (type:'contain'|'cover')=>(req, res) =>{
const {width, height} = res.props;
let resizer = sharp().resize(width, height).withoutEnlargement();
if (width && height) {
if (type === 'contain') {
//Resize the image according to background-size contain
resizer = resizer.max();
} else if (type === 'cover') {
//Resize the image according to background-size cover
resizer = resizer.min();
}
}
return resizer
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment