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));
Спасибо за ответ.