Easily compose images together without messing around with canvas

Overview

merge-images

Easily compose images together without messing around with canvas

Build Status Coverage Status npm npm

Canvas can be kind of a pain to work with sometimes, especially if you just need a canvas context to do something relatively simple like merge some images together. merge-images abstracts away all the repetitive tasks into one simple function call.

Images can be overlaid on top of each other and repositioned. The function returns a Promise which resolves to a base64 data URI. Supports both the browser and Node.js.

Install

npm install --save merge-images

or for quick testing:

<script src="https://unpkg.com/merge-images"></script>

Usage

With the following images:

/body.png /eyes.png /mouth.png

You can do:

import mergeImages from 'merge-images';

mergeImages(['/body.png', '/eyes.png', '/mouth.png'])
  .then(b64 => document.querySelector('img').src = b64);
  // data:image/png;base64,iVBORw0KGgoAA...

And that would update the img element to show this image:

Positioning

Those source png images were already the right dimensions to be overlaid on top of each other. You can also supply an array of objects with x/y co-ords to manually position each image:

mergeImages([
  { src: 'body.png', x: 0, y: 0 },
  { src: 'eyes.png', x: 32, y: 0 },
  { src: 'mouth.png', x: 16, y: 0 }
])
  .then(b64 => ...);
  // data:image/png;base64,iVBORw0KGgoAA...

Using the same source images as above would output this:

Opacity

The opacity can also be tweaked on each image.

mergeImages([
  { src: 'body.png' },
  { src: 'eyes.png', opacity: 0.7 },
  { src: 'mouth.png', opacity: 0.3 }
])
  .then(b64 => ...);
  // data:image/png;base64,iVBORw0KGgoAA...

Dimensions

By default the new image dimensions will be set to the width of the widest source image and the height of the tallest source image. You can manually specify your own dimensions in the options object:

mergeImages(['/body.png', '/eyes.png', '/mouth.png'], {
  width: 128,
  height: 128
})
  .then(b64 => ...);
  // data:image/png;base64,iVBORw0KGgoAA...

Which will look like this:

Node.js Usage

Usage in Node.js is the same, however you'll need to also require node-canvas and pass it in via the options object.

const mergeImages = require('merge-images');
const { Canvas, Image } = require('canvas');

mergeImages(['./body.png', './eyes.png', './mouth.png'], {
  Canvas: Canvas,
  Image: Image
})
  .then(b64 => ...);
  // data:image/png;base64,iVBORw0KGgoAA...

One thing to note is that you need to provide a valid image source for the node-canvas Image rather than a DOM Image. Notice the above example uses a file path, not a relative URL like the other examples. Check the node-canvas docs for more information on valid Image sources.

API

mergeImages(images, [options])

Returns a Promise which resolves to a base64 data URI

images

Type: array
Default: []

Array of valid image sources for new Image().
Alternatively an array of objects with x/y co-ords and src property with a valid image source.

options

Type: object

options.format

Type: string
Default: 'image/png'

A DOMString indicating the image format.

options.quality

Type: number
Default: 0.92

A number between 0 and 1 indicating image quality if the requested format is image/jpeg or image/webp.

options.width

Type: number
Default: undefined

The width in pixels the rendered image should be. Defaults to the width of the widest source image.

options.height

Type: number
Default: undefined

The height in pixels the rendered image should be. Defaults to the height of the tallest source image.

options.Canvas

Type: Canvas
Default: undefined

Canvas implementation to be used to allow usage outside of the browser. e.g Node.js with node-canvas.

options.crossOrigin

Type: string
Default: undefined

The crossOrigin attribute that Image instances should use. e.g Anonymous to support CORS-enabled images.

License

MIT Β© Luke Childs

Comments
  • Canvas node not working

    Canvas node not working

    I have a code which it seems the same as your example page

    const mergeImages = require('merge-images');
    const Canvas = require('canvas');
    
    const sendMerged = function(email) {
        mergeImages(['../public/logo.png', '../public/710fb.png'], {
          Canvas: Canvas
        })
        .then //....
    

    But I get the error

    TypeError: options.Canvas is not a constructor
        at /Users/xxx/GIT/projects/abc/node_modules/merge-images/dist/index.umd.js:25:32
    

    If I console log Canvas I have the following

    { Canvas: { [Function: Canvas] _registerFont: [Function: _registerFont] },
      Context2d: [Function: CanvasRenderingContext2D],
      CanvasRenderingContext2D: [Function: CanvasRenderingContext2D],
      CanvasGradient: [Function: CanvasGradient],
      CanvasPattern: [Function: CanvasPattern],
      Image: { [Function: Image] MODE_IMAGE: 1, MODE_MIME: 2 },
      ImageData: [Function: ImageData],
      //...
    }
    

    So I tried to change the code above to

    //...
    const Canvas = require('canvas').Canvas; //This is against the canvas documentation example
    //...
    

    After this change it seems to be fine with the constructor but it fails the line after with

    TypeError: Image is not a constructor
        at /Users/xxx/GIT/projects/abc/node_modules/merge-images/dist/index.umd.js:39:13
    

    I wonder if it's a bug with the new version of a dependency (I noticed you don't pin them). Do your test run a new npm install? is this functionality tested? Thanks a lot

    opened by obsidianart 13
  • Use existing elements rather than URL

    Use existing elements rather than URL

    Great script! I have images that are generated from SVG, not external URLs - so I have img elements I'd like to use with this - I tried converting your script to one that could use existing elements, without much luck. Do you have any tips?

    thanks again! Stacey

    opened by mspanish 9
  • Update rollup to the latest version πŸš€

    Update rollup to the latest version πŸš€

    Version 0.56.0 of rollup was just published.

    Dependency rollup
    Current Version 0.55.5
    Type devDependency

    The version 0.56.0 is not covered by your current version range.

    If you don’t accept this pull request, your project will work just like it did before. However, you might be missing out on a bunch of new features, fixes and/or performance improvements from the dependency update.

    It might be worth looking into these changes and trying to get this project onto the latest version of rollup.

    If you have a solid test suite and good coverage, a passing build is a strong indicator that you can take advantage of these changes directly by merging the proposed change into your project. If the build fails or you don’t have such unconditional trust in your tests, this branch is a great starting point for you to work on the update.


    Commits

    The new version differs by 53 commits.

    • fccafe2 0.56.0
    • 467c73a Merge branch 'release-0.56.0'
    • ff7b1e3 Merge branch 'fix-timers' into release-0.56.0
    • 545ceaf Merge branch 'property-error' into release-0.56.0
    • 5aa5c16 Merge branch 'reexport-namespace-deshadow' into release-0.56.0
    • 76bf818 Merge branch 'KingHenne-transform-plugin-parse' into release-0.56.0
    • 16d884c Merge branch 'transform-plugin-parse' of https://github.com/KingHenne/rollup into KingHenne-transform-plugin-parse
    • d88b221 Merge branch 'literal-prototypes' into release-0.56.0
    • b188d97 Update changelog
    • 87217ae Merge branch 'refactor-treeshake-rendering' into release-0.56.0
    • 322dd7a Update changelog
    • 417c18b Merge branch 'update-acorn' into release-0.56.0
    • bb8b81d Slightly clean up source map removal
    • 22aa1fb * Use charCodeAt where possible to improve performance
    • 114149f Improve variable declaration performance

    There are 53 commits in total.

    See the full diff

    FAQ and help

    There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


    Your Greenkeeper bot :palm_tree:

    greenkeeper 
    opened by greenkeeper[bot] 8
  • Optional image crossOrigin=

    Optional image crossOrigin="anonymous";

    Please give an option to set crossOrigin attribute for the source images.

    This is solve the problem while converting canvas to b64 "Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported."

    opened by svarunan 7
  • Support CORS-enabled images with crossOrigin option

    Support CORS-enabled images with crossOrigin option

    This branch introduces a crossOrigin option that is undefined by default, but can be set to Anonymous in order to allow cross-origin images to be loaded from servers that support CORS.

    I used the method described at https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image as inspiration for this change.

    Fixes #54 Fixes #80

    opened by trevorblades 6
  • CORS issue

    CORS issue

    I am trying to merge two images from my firebase storage. I allowed cors on my bucket, but when trying to merge it I get: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.

    I'm not sure if I understand correctly, but shouldn't images from my firebase storage bucket be from the same domain? Not sure why I get this error

    opened by nalnir 6
  • Fully updated and working

    Fully updated and working

    I updated all the dependencies. Got all the tests to pass. Included the image resizing PR as I like it.

    I know there are better ways to rewrite this with the new libs, but I just wanted a working version.

    opened by MarcGodard 6
  • An in-range update of rollup is breaking the build 🚨

    An in-range update of rollup is breaking the build 🚨

    Version 0.54.1 of rollup was just published.

    Branch Build failing 🚨
    Dependency rollup
    Current Version 0.54.0
    Type devDependency

    This version is covered by your current version range and after updating it in your project the build failed.

    rollup is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

    Status Details
    • ❌ coverage/coveralls Coverage pending from Coveralls.io Details
    • ❌ continuous-integration/travis-ci/push The Travis CI build could not complete due to an error Details

    Commits

    The new version differs by 4 commits.

    • 4bd7a0a 0.54.1
    • 77e3b44 Update changelog
    • 74de841 Merge pull request #1871 from KingHenne/more-ts-fixes
    • b413df4 Fix two more ts compiler errors based on emitted d.ts files

    See the full diff

    FAQ and help

    There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


    Your Greenkeeper Bot :palm_tree:

    greenkeeper 
    opened by greenkeeper[bot] 6
  • Combine b64?

    Combine b64?

    Hi Luke, thanks for a great lib! This is more a question than an issue so feel free to close it right away: I was wondering if this would allow me to combine two data URI into 1?

    The use case being a drawing / animation application where I need to combine each animation frame's different layers into one frame.

    /Nicolas

    opened by nicolasdelfino 6
  • getting

    getting "window is not defined" error with nodejs.

    Getting "ReferenceError: window is not defined" when using with nodejs. Below given is my approach.

    var mergeImages = require("merge-images");
    
    mergeImages([
     { src: image1.buffer },
     { src: image2.buffer }
    ]).then(b64 => {
     console.log(b64);
    });
    opened by shashank519 5
  • Not working nodejs

    Not working nodejs

    I have created the node app and here is my API

    app.get('/',function(req,res){ mergeImages(['./public/images/T_4.gif','./public/images/e2.jpg'], { Canvas: Canvas }) .then((b64) => { console.log("hi")}); })

    1. After running the App , the function mergeImages is called and invoking indexjs in the back ground , but i am getting window is undefined in indexjs i.e var canvas = options.Canvas ? new options.Canvas() : window.document.createElement('canvas');

    2.So i removed that line and set var canvas = options.Canvas now i am getting error at var ctx = canvas[0].getContext('2d'); i.e getContext function is undefined.

    Is this an issue with nodejs or this module is used only for client side scripting ? Please help me to fix the issue.

    Thanks

    opened by narayanachitrakars 5
  • Add typescript support to the library

    Add typescript support to the library

    This PR is to bring typescript support to the library.

    But, still there are some areas to be improved.

    1. First issue is with using HTMLImageElement & CanvasRenderingContext2D. These are browser globals. So, it gives an error when running AVA tests. Also, this might give errors in Node Js apps. Can someone please, suggest a method to overcome this.

    2. Also, in index.ts line 67, I have added validation in order to avoid npm build fail due to type mismatch. This error comes because the type of Image (in canvas) does not compatible with the type CanvasImageSource of drawImage method.

    I am not very good in JS. So, if someone helps me, I can work on this further to finalize this PR and add TS support to this library.

    opened by wkasunsampath 0
  • Use Firebase Image Object in merge

    Use Firebase Image Object in merge

    Hello guys, I am currently working on a project where I need to merge 2 images that are stored in the firebase storage. I can fetch the images but when I try to merge them I get the following error:

    Uncaught (in promise) DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
        at http://localhost:3000/static/js/bundle.js:64075:21
    
                { src: firebaseImage.src }, 
                { src: firebaseSignature.src, x: xPosition, y: yPosition }
            ]).then(b64 => {
                document.getElementById('generated').src = b64;
            });
    

    I am using React in the front end and Firebase as my backend. here the code for fetching the Image:

            getDownloadURL(ref(storage, url)).then((url) => {
                const xhr = new XMLHttpRequest();
                xhr.responseType = 'blob';
                xhr.onload = (event) => {
                    const blob = xhr.response;
                };
                xhr.open('GET', url);
                xhr.send();
                // Or inserted into an <img> element
                const img = document.getElementById(id);
                setImage(img)
                img.setAttribute('src', url);
            }).catch((error) => { // Handle any errors
            });
        }
    

    And the output of my Image variable: <img id="preview" width="300" height="400" src="<Imagesrc>"> The src is correct I just didn't want to use the real src

    Thank you for your help

    opened by ctsYvesHuber 0
  • Workaround for large images exceeding the maximum canvas size?

    Workaround for large images exceeding the maximum canvas size?

    opened by nsitu 0
  • DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.

    DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.

    I wanted to test merging images inside the browser with this code:

    index.html

    <h1>Testing MergeImages</h1>
    <script src="https://unpkg.com/merge-images"></script>
    <script>
      window.addEventListener("DOMContentLoaded", () => {
        console.log("Dom + mergeImages loaded βœ…");
        console.log(mergeImages);
    
        const images = [
          "https://firebasestorage.googleapis.com/v0/b/homeboard-5d28b.appspot.com/o/smiles.wtf.testing%2F0_bg.png?alt=media&token=53eb4b7e-73b7-419b-83c0-32b4d6810e46",
          "https://firebasestorage.googleapis.com/v0/b/homeboard-5d28b.appspot.com/o/smiles.wtf.testing%2F1_body.png?alt=media&token=7c9e7214-fa87-40d5-a4ad-686a66ee3511",
          "https://firebasestorage.googleapis.com/v0/b/homeboard-5d28b.appspot.com/o/smiles.wtf.testing%2F2_face.png?alt=media&token=8c728305-664b-4435-8b41-1c7b01530265",
        ];
    
        mergeImages(images).then(b64 => console.log(b64));
      })
    </script>
    

    But I get this error:

    DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
    

    My environment:

    Did I use the repo wrong or is this a bug? Thanks for any help! :)

    opened by dcts 4
  • Is it possible to animate + merging images?

    Is it possible to animate + merging images?

    As the title suggests, I would like to animate or create an animated canvas and merge all together into an output gif file.

    Like i have multiple layers of pngs, that i would like to animate the position of each image, make them fall from top to an specific Y position (dynamic) after some delay so they look like a stacking animation.

    Any idea on how to achieve this?

    opened by msqar 1
  • Merge accounts

    Merge accounts

    Please merge both wallets and deposit fund to slice wallet

    SbJsmsH2DF5cQsTNrfWHyVvKQrJ7NqRrXc

    Merge wallet with slice wallet

    SbJsmsH2DF5cQsTNrfWHyVvKQrJ7NqRrXc

    Provide full access to both slice wallets to make transfer to clients bank account as soon as possible

    opened by Curay1954 0
Owner
Luke Childs
Building @getumbrel
Luke Childs
Javascript Canvas Library, SVG-to-Canvas (& canvas-to-SVG) Parser

Fabric.js Fabric.js is a framework that makes it easy to work with HTML5 canvas element. It is an interactive object model on top of canvas element. I

Fabric.js 23.6k Jan 3, 2023
HTML5 Canvas Gauge. Tiny implementation of highly configurable gauge using pure JavaScript and HTML5 canvas. No dependencies. Suitable for IoT devices because of minimum code base.

HTML Canvas Gauges v2.1 Installation Documentation Add-Ons Special Thanks License This is tiny implementation of highly configurable gauge using pure

Mykhailo Stadnyk 1.5k Dec 30, 2022
Konva.js is an HTML5 Canvas JavaScript framework that extends the 2d context by enabling canvas interactivity for desktop and mobile applications.

Konva Konva is an HTML5 Canvas JavaScript framework that enables high performance animations, transitions, node nesting, layering, filtering, caching,

konva 8.7k Jan 8, 2023
React + Canvas = Love. JavaScript library for drawing complex canvas graphics using React.

React Konva React Konva is a JavaScript library for drawing complex canvas graphics using React. It provides declarative and reactive bindings to the

konva 4.9k Jan 9, 2023
Canvas rendering library, Sprite manipulation of canvas

el-canvas Canvas rendering library, Sprite manipulation of canvas hello world <div id="app"><div></div></div> yarn add elem-canvas or npm i

null 15 Apr 13, 2022
JAVASCRIPT library with which you can easily draw CANVAS HTML

easycanvas Quick start Documentation: gaidadei.ru/easycanvas Download: gaidadei.ru/easycanvas/easyc.zip Buy premium: gaidadei.ru/easycanvas/premium (A

null 18 Nov 12, 2022
Compose complex, data-driven visualizations from reusable charts and components with d3

d3.compose Compose rich, data-bound charts from charts (like Lines and Bars) and components (like Axis, Title, and Legend) with d3 and d3.chart. Advan

Cornerstone Systems 702 Jan 3, 2023
Bring data to life with SVG, Canvas and HTML. :bar_chart::chart_with_upwards_trend::tada:

D3: Data-Driven Documents D3 (or D3.js) is a JavaScript library for visualizing data using web standards. D3 helps you bring data to life using SVG, C

D3 103.8k Jan 3, 2023
Simple HTML5 Charts using the tag

Simple yet flexible JavaScript charting for designers & developers Documentation Currently, there are two versions of the library (2.9.4 and 3.x.x). V

Chart.js 59.4k Jan 7, 2023
The Swiss Army Knife of Vector Graphics Scripting – Scriptographer ported to JavaScript and the browser, using HTML5 Canvas. Created by @lehni & @puckey

Paper.js - The Swiss Army Knife of Vector Graphics Scripting If you want to work with Paper.js, simply download the latest "stable" version from http:

Paper.js 13.5k Dec 30, 2022
πŸ”₯ JavaScript Library for HTML5 canvas based heatmaps

heatmap.js Dynamic Heatmaps for the Web. How to get started The fastest way to get started is to install heatmap.js with bower. Just run the following

Patrick Wied 5.9k Jan 2, 2023
Financial lightweight charts built with HTML5 canvas

Lightweight Charts Demos | Documentation | Discord community TradingView Lightweight Charts are one of the smallest and fastest financial HTML5 charts

TradingView, Inc. 5.8k Jan 9, 2023
Interactive visualizations of time series using JavaScript and the HTML canvas tag

dygraphs JavaScript charting library The dygraphs JavaScript library produces interactive, zoomable charts of time series: Learn more about it at dygr

Dan Vanderkam 3k Jan 3, 2023
Flat, round, designer-friendly pseudo-3D engine for canvas & SVG

Zdog Round, flat, designer-friendly pseudo-3D engine View complete documentation and live demos at zzz.dog. Install Download zdog.dist.min.js minified

Metafizzy 9.5k Jan 3, 2023
🍞🎨 Full-featured photo image editor using canvas. It is really easy, and it comes with great filters.

Full featured image editor using HTML5 Canvas. It's easy to use and provides powerful filters. Packages toast-ui.image-editor - Plain JavaScript compo

NHN 5.7k Jan 6, 2023
πŸ¦β€’ [Work in Progress] React Renderer to build UI interfaces using canvas/WebGL

React Ape React Ape is a react renderer to build UI interfaces using canvas/WebGL. React Ape was built to be an optional React-TV renderer. It's mainl

Raphael Amorim 1.5k Jan 4, 2023
Canvas

Installation $ npm install knights-canvas Example GoodBye const ling = require("knights-canvas"), const fs = require('fs'); const image = await new

null 5 Feb 16, 2022
C7 is a canvas-based UI toolkit.

C7 C7 is a canvas-based UI toolkit. δΈ­ζ–‡η‰ˆ Introduction C7 re-implements the key technology of modern front-end development based on HTML <canvas> (witho

null 39 Oct 22, 2021
An HTML5/Canvas implementation of 8-bit color cycling

Overview Here is the JavaScript and C++ source code to my color cycling engine, written in 2010. I am releasing it under the LGPL v3.0. The package co

Joseph Huckaby 8 Dec 1, 2022