Tile four images together using Node.js and GraphicsMagick

Akseli Palén picture Akseli Palén · Jun 28, 2013 · Viewed 7.1k times · Source

I have four 256x256 px images: a.jpg, b.jpg, c.jpg and d.jpg. I would like to merge them together to produce 2x2 mosaic image. The resulting image should be also 256x256 px.

Like this:

+---+---+
| a | b |
+---+---+
| c | d |
+---+---+

Using plain GraphicsMagick and command line this can be done with

gm convert -background black \
    -page +0+0      a.jpg \
    -page +256+0    b.jpg \
    -page +0+256    c.jpg \
    -page +256+256  d.jpg \
    -minify \
    -mosaic output.jpg

But the problem is, how to do this using GraphicsMagick within Node.js?

gm('a.jpg')
    .append('b.jpg')
    .append('c.jpg')
    .append('d.jpg')
    .write('output.jpg', function (err) {})
// Produces 1x4 mosaic with dimensions 256x1024 px, not what I wanted

Answer

Akseli Palén picture Akseli Palén · Jun 28, 2013

Found the solution! It seems that the public API of gm does not provide any proper methods for what I needed. The solution was to use not-so-public .in method which makes possible to insert custom GraphicsMagick arguments.

The following code takes in four 256x256 images, merges them to 2x2 grid on 512x512 canvas, halves the size to 256x256 using fast linear interpolation and saves the result to output.jpg.

var gm = require('gm');

// a b c d  ->  ab
//              cd
gm()
    .in('-page', '+0+0')  // Custom place for each of the images
    .in('a.jpg')
    .in('-page', '+256+0')
    .in('b.jpg')
    .in('-page', '+0+256')
    .in('c.jpg')
    .in('-page', '+256+256')
    .in('d.jpg')
    .minify()  // Halves the size, 512x512 -> 256x256
    .mosaic()  // Merges the images as a matrix
    .write('output.jpg', function (err) {
        if (err) console.log(err);
    });