merge-images icon indicating copy to clipboard operation
merge-images copied to clipboard

Is it possible to resize the merging image?

Open bsor-dev opened this issue 7 years ago • 3 comments
trafficstars

mergeImages([ { src: 'body.png', x: 0, y: 0 }, { src: 'eyes.png', x: 32, y: 0, height:500, width:500 }, { src: 'mouth.png', x: 16, y: 0, height:500, width:500 } ])

bsor-dev avatar Aug 04 '18 12:08 bsor-dev

PR #63 could solve this, hope it gets merged.

guumaster avatar Sep 21 '18 16:09 guumaster

I would also like this PR #63 merged.

MarcGodard avatar Mar 12 '19 20:03 MarcGodard

For anyone who wants to use it in plain JS and doesn't want to wait for the PR to be included. The closure is taken from the unkpg-package.

merge-images.js
(function (global, factory) {
	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
		typeof define === 'function' && define.amd ? define(factory) :
			(global.mergeImages = factory());
}(this, (function () {
	'use strict';

	// Defaults
	const defaultOptions = {
		format: 'image/png',
		quality: 0.92,
		width: undefined,
		height: undefined,
		Canvas: undefined,
		crossOrigin: undefined
	};

	const getX = (image, width) => {
		if (image.right != undefined)
			return width - (image.right + (image.width || image.img.width));
		return image.left || image.x || 0;
	}

	const getY = (image, height) => {
		if (image.bottom != undefined)
			return height - (image.bottom + (image.height || image.img.height));
		return image.top || image.y || 0;
	}

	// Return Promise
	const mergeImages = (sources = [], options = {}) => new Promise(resolve => {
		options = Object.assign({}, defaultOptions, options);

		// Setup browser/Node.js specific variables
		const canvas = options.Canvas ? new options.Canvas() : window.document.createElement('canvas');
		const Image = options.Image || window.Image;

		// Load sources
		const images = sources.map(source => new Promise((resolve, reject) => {
			// Convert sources to objects
			if (source.constructor.name !== 'Object') {
				source = { src: source };
			}

			// Resolve source and img when loaded
			var img = new Image();
			img.crossOrigin = options.crossOrigin;
			img.onerror = () => reject(new Error('Couldn\'t load image'));
			img.onload = () => resolve(Object.assign({}, source, { img }));
			img.src = source.src;
		}));

		// Get canvas context
		const ctx = canvas.getContext('2d');

		// When sources have loaded
		resolve(Promise.all(images)
			.then(images => {
				// Set canvas dimensions
				const getSize = dim => options[dim] || Math.max(...images.map(image => image.img[dim]));
				canvas.width = getSize('width');
				canvas.height = getSize('height');

				// Draw images to canvas
				images.forEach(image => {
					ctx.globalAlpha = image.opacity ? image.opacity : 1;
					return ctx.drawImage(image.img, getX(image, canvas.width), getY(image, canvas.height), image.width || image.img.width, image.height || image.img.height);
				});

				if (options.Canvas && options.format === 'image/jpeg') {
					// Resolve data URI for node-canvas jpeg async
					return new Promise((resolve, reject) => {
						canvas.toDataURL(options.format, {
							quality: options.quality,
							progressive: false
						}, (err, jpeg) => {
							if (err) {
								reject(err);
								return;
							}
							resolve(jpeg);
						});
					});
				}

				// Resolve all other data URIs sync
				return canvas.toDataURL(options.format, options.quality);
			}));
	});

	return mergeImages;

})));
//# sourceMappingURL=index.umd.js.map

lprc avatar Jul 09 '20 08:07 lprc