使用Nodejs中的gm调整大小和组合两个或多个图像

4

给定两张图片,分别位于img文件夹下(大小为1024x768),命名为img1.png和img2.png。我需要将img2调整大小(比如300x300),并将其放置在img1的左上角,距离img1顶部和左侧各100像素。最终结果应该是一张大小为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个小时阅读了一些帖子(只能在这里找到一些讨论:如何使用gm node.js进行合成?和这里:在NodeJS的graphicsMagick中调整大小一个对象并将两个gm对象组合在一起(实际上这个不回答问题),我找不到任何流或缓冲区内存中执行此操作的解决方案。可以在写入临时文件时执行此操作。是否有人能够找到在内存中调整大小和合并图像的解决方案?
3个回答

4

使用ImageMagick代替GraphicMagic;

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

首先看一下这张图片:

enter image description here

在花费几分钟研究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!');
    });

顺便提一下,对于合成图像来说,node-canvas 真的非常好用,而且比 gm 或 im 更快。 - Ahmet Cetin
还没有尝试过,但是我会在完成当前项目后看一下。不过我看到你仍然需要安装一些包。Canvas非常适合对齐和定位实体。感谢您的建议。 - Canser Yanbakan
是的,它需要cairo和pango。 - Ahmet Cetin
这对我不起作用。输出只是未经修改的背景。我已经子类化了ImageMagick。 - Joe Ainsworth
我不得不将'Dst_Over'更改为'Over'。 - Joe Ainsworth
目前,gm.composite() 只接受文件路径,不要尝试使用流或缓冲区。 - nikoskip

1

最终我做到了,这里发布供需要的人参考:

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,所以将使用ImageMagick而不是GraphicMagic。请查看我的答案。 - Canser Yanbakan

0

您可以利用重力来帮助定位您的图层,然后使用几何学进行微调,例如:

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);
   })

使用这种模式,您可以添加任意数量的图层,但请记住它会将所有图像读入内存,因此如果您有许多由大型图像组成的图层,则可能只想一次处理两个。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接