在 Nodejs 中使用 gm 调整大小并合成两个或多个图像

Resize and compose two or more images using gm in Nodejs

给定两张图片,比如在 img(大小为 1024x768)文件夹下(img1.png 和 img2.png),我需要调整 img2 的大小(比如 300x300)并在 x 和 y 中放置 img1 (比如 100、200)从 img1 的左上角开始。最终结果应该是 1024x768 大小的图像。

使用 gm (https://github.com/aheckmann/gm),试过这个:

gm('./img/img1.png')
.composite('./img/img2.png')
.geometry('300x300+100+200')
.write('resultGM.png', (err) => {
  if (err) console.log(err);
});

预期(由于整个操作链)它会生成 300x300 图像。 然后我试了这个:

gm('./img/img1.png')
.composite(
  gm('./img/img2.png')
  .geometry('300x300+100+200')
)
.write('resultGM.png', (err) => {
  if (err) console.log(err);
});

希望复合函数接受缓冲区,但是没有机会,它只接受文件路径,并且报错。在花了 2-3 小时阅读了几篇文章后(只能在这里找到一些讨论:How to do composite with gm node.js? and here: Combine two gm objects while resizing one of them in graphicsMagick for NodeJS(这个实际上没有回答问题),我找不到任何解决方案来在内存中使用流或缓冲区。可以在写入临时文件时执行此操作。是否有人可以找到内存中调整大小和动态合并图像的解决方案?

终于搞定了,这里post供大家参考:

gm()
.in('-geometry', '+0+0')
.in('./img/img1.png')
.in('-geometry', '300x300+100+200')
.in('./img/img2.png')
.flatten()
.write('resultGM.png', function (err) {
  if (err) console.log(err);
});

使用 ImageMagick 代替 GraphicMagic;

经过几个小时的搜索,我终于想出了如何使用 gm 合并两个调整大小和重新排序图层位置(上方、下方等)的图像。

先来看这张图:

在浏览 ImageMagick 的 compose 帮助页面几分钟后,我看到了 DstOver 定位的用法。

http://www.imagemagick.org/Usage/compose/#dstover

所以,我已经尝试了下面的这段代码,它非常有效!

imageMagick(background)
    .composite(image)
    .in('-compose', 'Dst_Over')
    .in('-geometry', '253x253+15+15')
    .write(output, function (err) {
    if (err) console.error(err);
        else console.log('Compose OK!');
    });

您可以使用重力来帮助定位您的层,然后使用几何将其调入:

import * as graphics from 'gm';
const gm = graphics.subClass({ imageMagick: true });

type GravityDirection = 'NorthWest'
    | 'North'
    | 'NorthEast'
    | 'West'
    | 'Center'
    | 'East'
    | 'SouthWest'
    | 'South'
    | 'SouthEast';


 gm('pathToTopLayerImg')
   .in('pathToBaseImg')
   .gravity('Center')
   .geometry('+10+10')
   .out('-composite')
   .write('pathToDestination', err => {
      if (err) console.log(err);
   })

如果您想向基础图像添加额外的图层,则:

 gm('pathToFirstLayerImg')
   .in('pathToBaseImg')
   .gravity('Center')
   .geometry('+10+10')
   .out('-composite')
   .out('pathToSecondLayer')
   .out('-gravity', 'NorthWest')
   .out('-geometry', '+10+10')
   .out('-composite')
   .write('pathToDestination', err => {
      if (err) console.log(err);
   })

您可以使用此模式添加任意多的图层,但请记住,它会将所有图像读入内存,因此如果您有很多图层由大型图像组成,您可能只想一次只执行两个图片。