1

What am I trying to do?

I'm trying to stitch 2 images of the same size, according to predefined polygon using nodejs(gm). I succeeded to do so, but it is very cumbersome and time consuming. Looking for a shorter and better way to do so.

In details

I have 2 images size 256x256. I also have a predefined polygon (for example - [0,255],[0,50],[100,100], [255,50],[255,255],[0,255] ).

Note: Those images can have transparent pixels, and regular pixels.

My goal is to stitch the 2 images together, where the first image is cropped to have only what's in the polygon, and the other one only what is outside the polygon. For example, if image 1 is a completely red, and image 2 is completely yellow, the output of this small program should be: output

The current solution

I managed to do so, with the following code. But, it's long, cumbersome, and time consuming.


function createMaskAccordingToPolygon(polygon, imageFileName) {
gm(256, 256, '#ffffff')
    .fill('#000000')
    .drawPolygon([polygon])
    .toBuffer('PNG',(err, buffer) => {copyOrigPicOpacityOnMask(err, buffer, imageFileName)});
}

function copyOrigPicOpacityOnMask(err, buffer, imageFileName) {
   if (err) {
        console.log(err);
        throw err;
    }

    //Copies the opacity if the original image over the mask
    gm(buffer)
        .composite(imageFileName)
        .compose('copyOpacity')
        .toBuffer('PNG', (err, buffer) => {removeBlackFromAdjustedMask(err, buffer, imageFileName)});
}

function removeBlackFromAdjustedMask(err, buffer, imageFileName) {
    if (err) {
        console.log(err);
        throw err;
    }

    // Clears the black parts from the mask
    gm(buffer)
        .transparent('#ffffff')
        .write('poly-mask-adjusted-transparent' + imageFileName, (err) => {cutOrigImage(err, imageFileName)});
}

function cutOrigImage(err, imageFileName) {
    if (err) {
        console.log(err);
        throw err;
    }

    gm(imageFileName)
        .composite('poly-mask-adjusted-transparent' + imageFileName)
        .compose('copyOpacity')
        .toBuffer('PNG', (err, buffer) => {endGame(err, buffer, imageFileName)});
}

function endGame(err, buffer, imageFileName) {
    if (err) {
        console.log(err);
        throw err;
    }

    console.log('success');

    gm(buffer)
        .write('end-' + imageFileName, () => {console.log('wrote')})

}

createMaskAccordingToPolygon([ [0,255],[0,50],[100,100], [255,50],[255,255],[0,255] ], 'image1.png');

createMaskAccordingToPolygon([[0,0],[0,50],[100,100],[255,50],[255,0],[0,0]], 'image2.png');

And then, using composite, in order to put one image over the other.

Any way to simplify and optimize it?

Thanks!

Noam Zweig
  • 11
  • 1

0 Answers0