UNPKG

qwebs

Version:
257 lines (219 loc) 10.1 kB
/*! * qwebs * Copyright(c) 2015 Benoît Claveau <benoit.claveau@gmail.com> * MIT Licensed */ "use strict"; const Jimp = require("jimp"); const DataError = require("./../dataerror"); class QJimp { constructor() { }; toImage(buffer) { return new Promise((resolve, reject) => { Jimp.read(buffer, (err, data) => { if (err) reject(err); else resolve(data); }); }); }; clone(image) { return Promise.resolve().then(() => { if (!image) throw new DataError({ message: "image is not defined." }); return image.clone(); }); }; toBuffer(image, contentType) { return new Promise((resolve, reject) => { if (!contentType) reject(new DataError({ message: "contentType is not defined." })); image.getBuffer(contentType, (err, data) => { if (err) reject(err); else resolve(data) }); }); }; size(image) { return Promise.resolve().then(() => { if (!image) throw new DataError({ message: "image is not defined." }); return { width: image.bitmap.width, height: image.bitmap.height }; }); }; resize(image, width, height) { return Promise.resolve().then(() => { if (!image) throw new DataError({ message: "image is not defined." }); if (!width) throw new DataError({ message: "width is not defined." }); if (!height) throw new DataError({ message: "height is not defined." }); return image.resize(width, height); }); }; crop(image, left, top, width, height) { return Promise.resolve().then(() => { if (!image) throw new DataError({ message: "image is not defined." }); if (left == null) throw new DataError({ message: "left is not defined." }); if (top == null) throw new DataError({ message: "top is not defined." }); if (width == null) throw new DataError({ message: "width is not defined." }); if (height == null) throw new DataError({ message: "height is not defined." }); return image.crop(left, top, width, height); }); }; cropAndResize(image, width, height) { return this.size(image).then(size => { if (!image) throw new DataError({ message: "image is not defined." }); if (!size) throw new DataError({ message: "size is not defined." }); if (!width) throw new DataError({ message: "width is not defined." }); if (!height) throw new DataError({ message: "height is not defined." }); let cropRatio = width / height; let imageRatio = size.width / size.height; if (cropRatio == imageRatio) { return this.resize(image, width, height); } if (cropRatio < imageRatio) { let resizedWidth = height * imageRatio; return this.resize(image, resizedWidth, height).then(resizedImage => { return this.size(resizedImage).then(resized => { let left = (resized.width - width) / 2; return this.crop(resizedImage, left, 0, width, height); }); }); } else { let resizedHeight = width / imageRatio; return this.resize(image, width, resizedHeight).then(resizedImage => { return this.size(resizedImage).then(resized => { let top = (resized.height - height) / 2; return this.crop(resizedImage, 0, top, width, height); }); }); } }); }; cropIfNeeded(image, width, height) { return this.size(image).then(size => { if (!image) throw new DataError({ message: "image is not defined." }); if (!size) throw new DataError({ message: "size is not defined." }); if (!width) throw new DataError({ message: "width is not defined." }); if (!height) throw new DataError({ message: "height is not defined." }); let cropRatio = width / height; let imageRatio = size.width / size.height; if (cropRatio == imageRatio) { return image; //no crop needed } if (cropRatio < imageRatio) { let resizedWidth = width / imageRatio; let left = (size.width - resizedWidth) / 2; return this.crop(image, left, 0, resizedWidth, size.height); } else { let resizedWidth = size.height * imageRatio; let left = (size.width - resizedWidth) / 2; return this.crop(image, left, 0, resizedWidth, size.height); } }); }; cropAndAddBackground(image, width, height) { return this.size(image).then(size => { if (!image) throw new DataError({ message: "image is not defined." }); if (!size) throw new DataError({ message: "size is not defined." }); if (!width) throw new DataError({ message: "width is not defined." }); if (!height) throw new DataError({ message: "height is not defined." }); return this.cropIfNeeded(image, width, height).then(cropped => { return this.size(cropped).then(size => { return this.clone(cropped).then(background => { let ratio = size.width / size.height; let bgWidth = Math.min(size.width / 2, 200); let bgHeight = bgWidth / ratio; let bgLeft = Math.max(size.width - bgWidth, 0) / 2; let bgTop = Math.max(size.height - bgHeight, 0) / 2; return this.crop(background, bgLeft, bgTop, bgWidth, bgHeight).then(background => { return this.resize(background, width, height).then(background => { return this.blur(background, 50).then(background => { return this.opacity(background, 0.5); }); }); }).then(background => { return this.scale(cropped, 0.75).then(cropped => { return this.size(cropped).then(thSize => { let x = (width - thSize.width) / 2; let y = (height - thSize.height) / 2; return this.blit(background, cropped, x, y); }); }); }); }); }); }); }); }; smartResize(image, width, height) { return Promise.resolve().then(() => { if (!image) throw new DataError({ message: "image is not defined." }); if (!width) throw new DataError({ message: "width is not defined." }); if (!height) throw new DataError({ message: "height is not defined." }); return this.size(image).then(size => { if (size.height < height && size.width < width) return this.cropAndAddBackground(image, width, height); else return this.cropAndResize(image, width, height); }); }); }; transform(image, size) { return this.smartResize(image, size.width, size.height); }; greyscale(image) { return Promise.resolve().then(() => { if (!image) throw new DataError({ message: "image is not defined." }); return image.greyscale(); }); }; contrast(image, val) { return Promise.resolve().then(() => { if (!image) throw new DataError({ message: "image is not defined." }); return image.contrast(val); }); }; blur(image, r) { return Promise.resolve().then(() => { if (!image) throw new DataError({ message: "image is not defined." }); return image.blur(r); }); }; opacity(image, f) { return Promise.resolve().then(() => { if (!image) throw new DataError({ message: "image is not defined." }); return image.opacity(f); }); }; scale(image, f) { return Promise.resolve().then(() => { if (!image) throw new DataError({ message: "image is not defined." }); return image.scale(f); }); }; blit(background, image, x, y, srcx, srcy, srcw, srch) { return Promise.resolve().then(() => { if (!image) throw new DataError({ message: "image is not defined." }); return background.blit(image, x, y, srcx, srcy, srcw, srch); }); }; lightness(image) { return Promise.resolve().then(() => { if (!image) throw new DataError({ message: "image is not defined." }); let fuzzy = 0.1; let bitmap = image.bitmap; let data = bitmap.data; let r,g,b, max_rgb; let light = 0; let len = data.length; for(let x = 0; x < len; x+=4) { r = data[x]; g = data[x+1]; b = data[x+2]; max_rgb = Math.max(Math.max(r, g), b); if (max_rgb >= 128) light++; } let lightness = light / (len / 4); return +lightness.toFixed(2); }); }; }; exports = module.exports = QJimp;