node.js: gm создает ошибку E2BIG для spawn при передаче слишком большого количества данных

Следующий код выдает ошибку:

const COUNT = 2528; // 2527 works, 2528 errors

const gm = require('gm').subClass({ imageMagick: true });

const brokenData = [];

for (let i = 0; i < COUNT; i++) {
  brokenData.push([
    Math.random() * 500, Math.random() * 500
  ]);
}

const tile = gm('./blank-tile.png')
  .resize(500, 500)
  .fill("red");

brokenData.forEach((point) => {
  tile.drawCircle(point[0], point[1], point[0] + 4, point[1]);
});

tile.write(__dirname + '/test.png', (err) => {
  if (err) {
    throw err;
  }

  console.log('success');
});

Что касается комментария, это нормально при рисовании 2527 кругов, но выдает ошибку в 2528 кругов. Это то же самое каждый раз, по крайней мере, на моей машине.

Вот ошибка:

Error: spawn E2BIG
    at ChildProcess.spawn (internal/child_process.js:358:11)
    at Object.spawn (child_process.js:533:9)
    at spawn (/Users/callumacrae/Sites/testing-gm/node_modules/cross-spawn/index.js:17:18)
    at gm._spawn (/Users/callumacrae/Sites/testing-gm/node_modules/gm/lib/command.js:224:14)
    at /Users/callumacrae/Sites/testing-gm/node_modules/gm/lib/command.js:101:12
    at series (/Users/callumacrae/Sites/testing-gm/node_modules/array-series/index.js:11:36)
    at gm._preprocess (/Users/callumacrae/Sites/testing-gm/node_modules/gm/lib/command.js:177:5)
    at gm.write (/Users/callumacrae/Sites/testing-gm/node_modules/gm/lib/command.js:99:10)
    at Object.<anonymous> (/Users/callumacrae/Sites/testing-gm/test.js:21:6)
    at Module._compile (internal/modules/cjs/loader.js:688:30)

Я предполагаю, что это происходит где-то в gm, так как я не предоставил длинных списков аргументов!

То же самое происходит, использую ли я imagemagick или graphicsmagick. Узловая версия 10.13.0.

Есть идеи?

1 ответ

Решение

Я не очень знаком с node-gm, но у меня такое ощущение, что .drawCircle(x1, y1, x2, y2) метод просто добавляет аргумент командной строки -draw "circle x1,y1 x2,y2", Таким образом, после 2527 команд рисования вы превышаете буфер аргументов.

С ImageMagick, если у вас есть большой список команд рисования, вы пишете в файл и говорите команде рисования читать из него.

Файл будет выглядеть примерно так...

# circles.txt
circle x1,y1 x2,y2
circle x1,y1 x2,y2
circle x1,y1 x2,y2
circle x1,y1 x2,y2

И ссылка на файл с символом (@) префикс.

convert ... -draw @cicles.txt ...

Таким образом, в качестве альтернативы, вы можете создать временный файл, написать команды рисования, а затем вызвать..

const tile = gm('./blank-tile.png')
  .resize(500, 500)
  .fill("red")
  .draw("@circles.txt");

Однако я не уверен, поддерживает ли node-gm это, и / или многие современные системы отключают MVG & TXT с протоколами безопасности по умолчанию. Стоит расследовать.

Другие вопросы по тегам