join-images
Version:
Merge multiple images into a single image
90 lines • 4.12 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.joinImages = void 0;
const tslib_1 = require("tslib");
const alignImage_1 = tslib_1.__importDefault(require("./utils/alignImage"));
const calcMargin_1 = tslib_1.__importDefault(require("./utils/calcMargin"));
const sharp_1 = tslib_1.__importDefault(require("sharp"));
const fs_1 = tslib_1.__importDefault(require("fs"));
const is_plain_obj_1 = tslib_1.__importDefault(require("is-plain-obj"));
function joinImages(images, { direction = 'vertical', color = { alpha: 0.5, b: 0, g: 0, r: 0 }, align = 'start', offset = 0, margin, } = {}) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
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* () {
let imageSrc = img;
let offsetX = 0;
let offsetY = 0;
if ((0, is_plain_obj_1.default)(img)) {
const { src, offsetX: x = 0, offsetY: y = 0 } = img;
offsetX = +x;
offsetY = +y;
imageSrc = src;
}
const meta = yield (0, sharp_1.default)(imageSrc).metadata();
const { width, height } = meta;
return {
buffer: typeof imageSrc === 'string'
? fs_1.default.readFileSync(imageSrc)
: imageSrc,
height,
offsetX,
offsetY,
width,
x: 0,
y: 0,
};
});
const imgs = yield Promise.all(images.map(processImg));
let totalX = 0;
let totalY = 0;
const imgData = 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, right, bottom, left } = (0, calcMargin_1.default)(margin);
const marginTopBottom = top + bottom;
const marginRightLeft = right + left;
const isVertical = direction === 'vertical';
const totalWidth = isVertical
? Math.max(...imgData.map(({ width, offsetX }) => width + offsetX))
: imgData.reduce((res, { width, offsetX }, index) => res + width + offsetX + Number(index > 0) * offset, 0);
const totalHeight = isVertical
? imgData.reduce((res, { height, offsetY }, index) => res + height + offsetY + Number(index > 0) * offset, 0)
: Math.max(...imgData.map(({ height, offsetY }) => height + offsetY));
const imageBase = (0, sharp_1.default)({
create: {
background: color,
channels: 4,
height: totalHeight + marginTopBottom,
width: totalWidth + marginRightLeft,
},
});
const compositeData = imgData.map((imgData, index) => {
const { buffer, x, y, offsetX, offsetY, width, height } = imgData;
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.joinImages = joinImages;
exports.default = joinImages;
//# sourceMappingURL=main.js.map