2014-06-30 43 views
28
var buf = require('fs').readFileSync('test.jpg'); 

gm().in('-page', '+0+0').in(buf,'test.jpg').write('output.jpg', function (err) { 
    if (err) console.log(err); 
}) 

在这种情况下,我想将缓冲区数据作为输入传递给gm.in()方法。如何将图像缓冲区数据传递给gm in()GraphicsMagic

以下是我参考的链接,但在其中,图像路径用作输入。我想使用缓冲区数据作为输入。我怎样才能做到这一点?

Tile four images together using Node.js and GraphicsMagick

+0

试图做同样的事情,我想在aws lambda上使用复合,所以我必须单独使用流。我在想,你可以命名流并重用它们,但目前为止没有成功。 – jgeerts

+0

'gm'上也有一个'page'函数 - 所以不用'in(“ - page”)',直接将缓冲区传递给'page'函数。那我认为应该工作。 – treecoder

回答

2

其实我创建的海报有两个不同的图像是一个模板图像“背景”和第二个是有一些文字顶部的形象。我试过gm,但我失去了图像质量。有人指导我使用缓冲区数据作为输入来改善图像质量。我尝试过,但不知道如何通过缓冲区数据作为输入。 因此最后我决定使用命令字符串来使用节点子进程。以下是我与您分享的示例代码。

var fs = require('fs'); 

var gm = require("gm"); 
var exec = require('child_process').exec; 
var IMAGEFILEPATH = "/images"; 
var gmcreateImage = function() { 

var imageConfig = {"topimage":{"density":"300x300","startx":925,"starty":650,"width":575,"height":825}, 
"offers": [ 
      {"startx": 75, "starty": 850, "msg": "SAVE 5$", "textcolor": "#4f61ac", "font": "Arial Bold", "fontsize":34,"stroke":{"color":"#4f61ac","width":4}}, 
      {"startx": 75, "starty": 970, "msg": "per gallon", "textcolor": "#4f61ac", "font": "Arial Bold", "fontsize":34,"stroke":{"color":"#4f61ac","width":4}}, 
      {"startx": 75, "starty": 1150, "msg": "With the purchase of", "textcolor": "black", "font": "Arial", "fontsize":18,"stroke":{"color":"black","width":1}}, 
      {"startx": 75, "starty": 1260, "msg": "any Pepsi Z0 S2", "textcolor": "black", "font": "Arial", "fontsize":16,"stroke":{"color":"black","width":1}}, 
      {"startx": 75, "starty": 1370, "msg": "on all flavours", "textcolor": "black", "font": "Arial", "fontsize":16,"stroke":{"color":"black","width":1}}, 
      {"startx": 75, "starty": 1480, "msg": "Ask for details.", "textcolor": "black", "font": "Arial", "fontsize":18,"stroke":{"color":"black","width":1}} 
]}; 
    var addLast=imageConfig.topimage.last; 
    var commandStr = "gm convert '-page' '+0+0' '-units' 'PixelsPerInch' '-density' '" + imageConfig.topimage.density + "' '" + IMAGEFILEPATH+ "/template.jpg' "; 

    var imageActualPosition={}; 
    imageActualPosition["x"] = imageConfig.topimage.startx; 
    imageActualPosition["y"] = imageConfig.topimage.starty; 

    if (!addLast) { 
     commandStr += " '-page' '+" + imageActualPosition["x"] + "+" + imageActualPosition["y"] + "' '" + IMAGEFILEPATH + "/top.jpg' "; 
    } 

    var offers = imageConfig.offers; 
    for (var i in offers) { 
     var color = offers[i].textcolor; 
     var startX = offers[i].startx; 
     var startY = offers[i].starty; 
     var font = offers[i].font; 
     var fontSize = offers[i].fontsize; 
     var msg = offers[i].msg; 
     var offerStr = ""; 
     if (offers[i].stroke) { 
      offerStr += " '-stroke' '" + offers[i].stroke.color + "' '-strokewidth' '" + offers[i].stroke.width + "'"; 
     } 
     offerStr += " '-fill' '" + color + "' '-pointsize' '" + fontSize + "' '-draw' 'text " + startX + " " + startY + " \"" + msg + "\"'"; 
     commandStr += offerStr; 
    } 
    if (addLast) { 
     commandStr += " '-page' '+" + imageActualPosition["x"] + "+" + imageActualPosition["y"] + "' '" + IMAGEFILEPATH + "/top.jpg' "; 
    } 
    var finalImage="done.jpg"; 
    commandStr += " '-mosaic' '-quality' '100' '" + IMAGEFILEPATH + finalImage + "'"; 
    exec(commandStr, function(err, stdout, stderr) { 
      if (err) { 
       console.log("Error while executing gm commands" + err); 
       return; 
      } else { 
       console.log("Done See your image"); 
      } 
    }) 
}; 
gmcreateImage(); 
+0

这不回答这个问题。您没有使用缓冲区数据进行处理,您正在使用与现有文件组合的子进程。很高兴它适合你,但它不属于这个问题的答案。 – imjared

+1

是的,我同意你这不是这个问题的答案。但我只是分享我是如何解决这个问题的。因为作为开发人员,我们必须找到解决方案可能采用不同的方法。 :) –

2

不修改GraphicsMagick本身的源代码,你不能。 gm模块通过命令行与GraphicsMagick程序进行交互。您通过.in()方法传递的参数正被转换为命令行参数。 GraphicsMagick程序只接受该参数的文件名,并且不会尝试处理任何直接形式的数据。

如果您确实需要在没有文件系统的情况下完成此项工作,则可以始终下载GraphicsMagick源代码并将CLI更改为接受某种形式的数据blob,而不是此参数的URL。

0

我还没有想出如何既与imagewatermark作为缓冲区做到这一点,但我已经找到了如何将图像保存为一个缓冲:

gm(imageBuffer) 
    .composite('./logo_path.png') 
    .geometry(geometry) 
    .gravity('SouthEast') 
    .dissolve(this.options.opacity) 
    .toBuffer(function (err, buffer) { 
     next(err, buffer, 'image/jpeg'); 
    }); 
}; 

检查出码这great library欲了解更多信息。

相关问题