Node.js imagemagick Ошибка: слишком много страниц в дереве страниц. при конвертации pdf в png - PullRequest
1 голос
/ 06 мая 2020

У меня возникли проблемы при преобразовании некоторых PDF-файлов в миниатюру PNG.

const outputStream = gm(Buffer.from(path, 'base64'))
        .selectFrame(0)
        .noProfile()
        .quality(60)
        .density(200)
        .background('white')
        .resize(600, 600)
        .setFormat('png');

Тогда я только что получил эту ошибку

Здесь вы можете увидеть эти pdf-файлы

Есть ли способ исправить эту ошибку или другой способ получить миниатюру pdf?

1 Ответ

1 голос
/ 06 мая 2020

Флаг -flatten решил мою проблему :)

В некоторых форматах файлов (например, PSD Photoshop) сложные изображения могут быть представлены в виде «слоев» (независимых изображений), которые должны быть композитным, чтобы получить окончательное исполнение. Параметр -flatten выполняет эту композицию. Последовательность изображений заменяется одним изображением, созданным путем компоновки каждого изображения по очереди с соблюдением операторов композиции и смещения страниц. Хотя -flatten сразу же полезен для удаления слоев, он также полезен как инструмент композиции общего назначения.

Поэтому я просто генерирую плоский PDF-файл, а затем конвертирую его в изображение это поможет кому-нибудь

const flattenPDFStream = gm(Buffer.from(path, 'base64'))
  .define('pdf:use-cropbox=true')
  .selectFrame(0)
  .flatten();

const flattenPDF = await gmToBuffer(flattenPDFStream);
const outputStream = gm(flattenPDF)
  .selectFrame(0)
  .noProfile()
  .quality(90)
  .background('white')
  .resize(400, 400)
  .setFormat('png');

GM для функции буферизации:

function gmToBuffer(data) {
  return new Promise((resolve, reject) => {
    data.stream((err, stdout, stderr) => {
      if (err) { return reject(err); }
      const chunks = [];
      stdout.on('data', chunk => {
        // Not best solution, but i need to control error message will not appear in pdf
        if (!chunk.includes('Error')) {
          chunks.push(chunk);
        } else {
          console.log(chunk.toString());
        }
      });
      // these are 'once' because they can and do fire multiple times for multiple errors,
      // but this is a promise so you'll have to deal with them one at a time
      stdout.once('end', () => { resolve(Buffer.concat(chunks)); });
      stderr.once('data', data => { reject(String(data)); });
    });
  });
}
...