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!