UNPKG

merge-base64

Version:
133 lines (116 loc) 3.16 kB
const Jimp = require('jimp'); const alignImage = require('./utils/alignImage'); const calcMargin = require('./utils/calcMargin'); module.exports = function mergeImages( images, { direction = false, color = 0x00000000, align = 'start', offset = 0, isPng = false, margin } = {} ) { if (!Array.isArray(images)) { throw new TypeError('`images` must be an array that contains images'); } if (images.length < 1) { throw new Error('At least `images` must contain more than one image'); } const processImg = async img => { const imgBuffer = await new Buffer.from(img, 'base64'); return Jimp.read(imgBuffer).then(imgObj => ({ img: imgObj })); }; return Promise.all(images.map(processImg)).then(imgs => { let totalX = 0; let totalY = 0; const imgData = imgs.reduce((res, { img, offsetX = 0, offsetY = 0 }) => { const { bitmap: { width, height } } = img; res.push({ img, x: totalX + offsetX, y: totalY + offsetY, offsetX, offsetY }); totalX += width + offsetX; totalY += height + offsetY; return res; }, []); const { top, right, bottom, left } = calcMargin(margin); const marginTopBottom = top + bottom; const marginRightLeft = right + left; const totalWidth = direction ? Math.max( ...imgData.map( ({ img: { bitmap: { width } }, offsetX }) => width + offsetX ) ) : imgData.reduce( ( res, { img: { bitmap: { width } }, offsetX }, index ) => res + width + offsetX + Number(index > 0) * offset, 0 ); const totalHeight = direction ? imgData.reduce( ( res, { img: { bitmap: { height } }, offsetY }, index ) => res + height + offsetY + Number(index > 0) * offset, 0 ) : Math.max( ...imgData.map( ({ img: { bitmap: { height } }, offsetY }) => height + offsetY ) ); const baseImage = new Jimp( totalWidth + marginRightLeft, totalHeight + marginTopBottom, color ); // Fallback for `Array#entries()` const imgDataEntries = imgData.map((data, index) => [index, data]); for (const [index, { img, x, y, offsetX, offsetY }] of imgDataEntries) { const { bitmap: { width, height } } = img; const [px, py] = direction ? [alignImage(totalWidth, width, align) + offsetX, y + index * offset] : [ x + index * offset, alignImage(totalHeight, height, align) + offsetY ]; baseImage.composite(img, px + left, py + top); } return baseImage.getBase64Async(isPng ? Jimp.MIME_PNG : Jimp.MIME_JPEG); // return baseImage; }); };