join-images
Version:
Merge multiple images into a single image
86 lines • 4.05 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.joinImages = joinImages;
const tslib_1 = require("tslib");
const is_plain_obj_1 = tslib_1.__importDefault(require("is-plain-obj"));
const sharp_1 = tslib_1.__importDefault(require("sharp"));
const alignImage_1 = tslib_1.__importDefault(require("./utils/alignImage"));
const calcMargin_1 = tslib_1.__importDefault(require("./utils/calcMargin"));
function isSharpInstance(value) {
return (typeof value === 'object' &&
value !== null &&
typeof value.clone === 'function' &&
typeof value.toBuffer === 'function');
}
function joinImages(images_1) {
return tslib_1.__awaiter(this, arguments, void 0, function* (images, { direction = 'vertical', color = { alpha: 0.5, b: 0, g: 0, r: 0 }, align = 'start', offset = 0, 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 = (img) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const { offsetX = 0, offsetY = 0, src, } = (0, is_plain_obj_1.default)(img)
? img
: { offsetX: 0, offsetY: 0, src: img };
const imageSrc = src;
const { data: buffer, info } = isSharpInstance(imageSrc)
? yield imageSrc.clone().toBuffer({ resolveWithObject: true })
: yield (0, sharp_1.default)(imageSrc).toBuffer({ resolveWithObject: true });
const { width = 0, height = 0 } = info;
return {
buffer,
height,
offsetX,
offsetY,
width,
x: 0,
y: 0,
};
});
const imgs = yield Promise.all(images.map(processImg));
let totalX = 0;
let totalY = 0;
const imageData = imgs.reduce((res, data) => {
const { width, height, offsetY, offsetX } = data;
res.push(Object.assign(Object.assign({}, data), { x: totalX + offsetX, y: totalY + offsetY }));
totalX += width + offsetX;
totalY += height + offsetY;
return res;
}, []);
const { top = 0, right = 0, bottom = 0, left = 0 } = (0, calcMargin_1.default)(margin);
const marginTopBottom = top + bottom;
const marginRightLeft = right + left;
const isVertical = direction === 'vertical';
const totalWidth = isVertical
? Math.max(...imageData.map(({ width, offsetX }) => width + offsetX))
: imageData.reduce((res, { width, offsetX }, index) => res + width + offsetX + Number(index > 0) * offset, 0);
const totalHeight = isVertical
? imageData.reduce((res, { height, offsetY }, index) => res + height + offsetY + Number(index > 0) * offset, 0)
: Math.max(...imageData.map(({ height, offsetY }) => height + offsetY));
const imageBase = (0, sharp_1.default)({
create: {
background: color,
channels: 4,
height: totalHeight + marginTopBottom,
width: totalWidth + marginRightLeft,
},
});
const compositeData = imageData.map((image, index) => {
const { buffer, x, y, offsetX, offsetY, width, height } = image;
const [px, py] = isVertical
? [(0, alignImage_1.default)(totalWidth, width, align) + offsetX, y + index * offset]
: [x + index * offset, (0, alignImage_1.default)(totalHeight, height, align) + offsetY];
return {
input: buffer,
left: Math.floor(px + left),
top: Math.floor(py + top),
};
});
imageBase.composite(compositeData);
return imageBase;
});
}
exports.default = joinImages;
//# sourceMappingURL=main.js.map