JS sharp: tiff2vips: out of order read at line 689 vips2png: unable to write

Столкнулся с такой проблемой, решить которую у меня буквально не хватает мозгов.

Создаю систему, которая берёт ряд больших изображений формата tiff и режет их на несколько мелких. Количество tiff'ов может достигать несколько сотен. Каждый из tiff'ов режется примерно на 25 изображений.

При решении этой задачи я решил использовать модуль sharp. В итоге функция резки работает. Она режет все файлы, но каждый этап резки около 50 "отрезков" не режутся (выдаёт на итоге пустое изображение) и выдаётся ошибка tiff2vips: out of order read at line 689 vips2png: unable to write.

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

Подскажите, что я неправильно понял и как мне понять, как делать правильно. Может статейку какую или ещё чего.

let fs = require('graceful-fs')
let sharp = require('sharp');
let path = require('path');
let xml2js = require('xml2js');
let iconvlite = require('iconv-lite');

const util = require('util');
const mysql = require('mysql2');
const async = require('async');
const stat = util.promisify(fs.stat);
const readFile = util.promisify(fs.readFile);
const mkdir = util.promisify(fs.mkdir);
const readdir = util.promisify(fs.readdir);

let dir = path.join(__dirname, '../public/projects/', projectName /*имя проекта для поиска его в папках с проектами - передаётся параметром при вызове функции*/, '/batches/00000000');
let pathsToTheAud = fs.readdirSync(dir);
let listOfBlanks = []; //список бланков

const pool = mysql.createPool({*данные для подключения к бд*}).promise();

//создание папки с проектом, если её нет
mkdir(path.join(__dirname, '../public/memory/', projectName), {recursive: true})
  .catch((err) => {
    console.log('err: ' + err);
  });

for (let item of pathsToTheAud) {
  //выборка необходимых файлов с данными ддя резки и ответов
  let files = fs.readdirSync(dir + '\\' + item);
  for (let file of files) {
    if (file.match(/AB/)) {
      if (path.extname(file).match(/XML/)) {
        listOfBlanks.push(path.join(item, path.parse(file).name));
      }
    }
  }
}

for (let item of listOfBlanks) {
  let xmlString = readFileSync_encoding(path.join(dir, item) + '.XML', 'UTF-16'); //.replace(/\?\?/,'');

  //вытаскиваем из файлов необходимые данные
  xml2js.parseStringPromise(xmlString, {attrkey: 'ATTR'})   
    .then((data) => { 
      for (let i = 0; i < 75; i++) { // число 75 взято от бaлды, лучше будет придумать что-нибудь по-надёжнее 

        let page = data.batch.page[0];

        if (page.block[i]._ && !(page.block[i].ATTR.blockName.match(/В\d\d/) === 'null' || page.block[i].ATTR.blockName.match(/В\d\d/) === null)) {

          /*штрих-код изображения: data.batch.page[0].block[1]._*/
          mkdir(path.join(__dirname, '../public/memory/', projectName, '/images/', page.block[3]._, '/', page.block[1]._ + '/'), {recursive: true})
            .then(()=>{
              //процесс резки изображения

              let croppedImage = path.join(__dirname, '../public/memory/', projectName, '/images/', data.batch.page[0].block[3]._, '/', /*штрих-код изображения*/
                data.batch.page[0].block[1]._ + '/') + data.batch.page[0].block[3]._ + '_' + path.parse(item).name + '_' + page.block[i].ATTR.blockName + '.png';

              readFile(path.join(__dirname, '../public/projects/', projectName, '/batches/00000000/') + item + '.' + (item + '.TIF').match(/TIF|TIFF/))
                .then((originalImage) => {
                  sharp(originalImage)
                    .extract({
                      'left': parseInt(page.block[i].ATTR.l, 10),
                      'top': parseInt(page.block[i].ATTR.t, 10),
                      'width': /*1071*/ parseInt(page.block[i].ATTR.r, 10) - parseInt(page.block[i].ATTR.l, 10),
                      'height': /*92*/ parseInt(page.block[i].ATTR.b, 10) - parseInt(page.block[i].ATTR.t, 10)
                    })
                    .toFile(croppedImage)
                    .then(()=>{
                      console.log('success: ' + item);
                    })
                    .catch(err => { /*тут вылазит ошибка - она не мешает процессу, но в итоге из примерно 30 тысяч обрезков около 100 пустые */

                      console.log('Error in toFile: ' + err.message 
                        + '\n left: ' + parseInt(page.block[i].ATTR.l) 
                        + '; top: ' + parseInt(page.block[i].ATTR.t, 10) 
                        + '; width: ' + (parseInt(page.block[i].ATTR.r, 10) - parseInt(page.block[i].ATTR.l, 10)) 
                        + '; height: ' + (parseInt(page.block[i].ATTR.b, 10) - parseInt(page.block[i].ATTR.t, 10)) 
                        + '; \n original image: ' + item + '; task: ' +page.block[i].ATTR.blockName + '\n');
                  });
                })
                .catch((err) => {
                  console.log('err in readFile: ' + err);
                });
            })
            .catch((err) => console.log('mkdir errror: ' + err));

Спасибо за ответ.


Ответы (0 шт):