web-dev-qa-db-ja.com

画像バッファデータをgmin()GraphicsMagickに渡す方法

_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()メソッドへの入力としてバッファデータを渡したいと思います。

以下は私が参照しているリンクですが、その中で、画像パスが入力として使用されています。バッファデータを入力として使いたい。これどうやってするの?

Node.jsとGraphicsMagickを使用して4つの画像を並べて表示します

30
Bharat Bhushan

GraphicsMagick自体のソースを変更しないと、変更できません。 gmモジュールは、コマンドラインを介してGraphicsMagickプログラムと対話します。 .in()メソッドを介して渡す引数は、コマンドライン引数に変換されています。 GraphicsMagickプログラムは、この引数のファイル名のみを受け入れ、直接形式のデータを処理しようとはしません。

ファイルシステムなしでこれを機能させる必要がある場合は、いつでもGraphicsMagickソースコードをダウンロードし、CLIを変更して、この引数のURLではなく何らかの形式のデータblobを受け入れることができます。

4
rrowland

実際、私は2つの異なる画像でポスターを作成していました。1つはテンプレート画像「背景」で、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();
2
Bharat Bhushan

別の応答で述べたように、graphicsmagickは入力としてバッファを許可していません。ただし、興味深いことに、HTTPURLを入力として許可します。 graphicsmagickのソースコードを変更せずにこれを機能させることに決めた場合は、次のようなことを試してください。

セットアップ

Uuidモジュールを追加します。

npm install uuid

バッファを保持するグローバルオブジェクトを作成します。

const magickbuffers = {}

スクリプトでhttpサーバーを作成します。

const uuid = require('uuid')
const http = require('http')
const magickserver = new http.Server()
const magickport = 9555

magickserver.on('request', (req, res) => {
  res.writeHead(200, { 'Content-Type': 'image/png' })
  if (magickbuffers[req.url]) {
    res.end(magickbuffers[req.url])
  }
  else {
    res.end("\n")
  }
})

magickserver.listen(magickport, () => {})

使用可能なローカルURLを提供するプロトタイプを作成して、graphicsmagickがローカルサーバー上のバッファーを見つけて画像として渡すことができるようにします。また、バッファーのストレージを処理します。

Object.prototype.openBuffer = function() {
  this.id = uuid()
  magickbuffers[`/${this.id}`] = this
  return `http://localhost:${magickport}/${this.id}`
}

完全に完了したら、バッファのクリーンアップを処理する別のプロトタイプを作成します。

Object.prototype.closeBuffer = function() {
  delete magickbuffers[`/${this.id}`]
  return true
}

使用法

望ましいが機能しない古い例:

gm()
  .in('-page', '+0+0')
  .in(bufferone) // gm cant use a buffer here, this won't work
  .in('-page', '+50+20')
  .in(buffertwo) // or here
  .mosaic()
  .stream('png', function (err, stdout, stderr) {
    stdout.pipe(writestream)
  })

動作する新しい方法:

let one = bufferone.openBuffer() 
let two = buffertwo.openBuffer() 
gm()
  .in('-page', '+0+0')
  .in(one) // gm recognizes this because 'one' is a url pointing to the buffer
  .in('-page', '+50+20')
  .in(two)
  .mosaic()
  .stream('png', function (err, stdout, stderr) {
    stdout.pipe(writestream)
    bufferone.closeBuffer() // do this once gm has completely finished using these buffers
    buffertwo.closeBuffer() // don't forget to do this for each buffer manipulated with .openBuffer()
  })    
1
fanfare

imagewatermarkの両方をバッファとして使用する方法はわかりませんが、画像をバッファとして保持する方法はわかりました。

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

詳細については、この 素晴らしいライブラリ のコードを確認してください。

0
Loourr