我尝试从目录中的所有图像中获取CSV文件。我在文件夹中有大约20-30张图片。问题是我的代码只适用于目录中的两个图像,而我使用foreach循环。我无法理解为什么会这样。它就是:
var fs = require('fs');
var jpeg = require('jpeg-js');
var Jimp = require("jimp");
var Promises = require('promise');
fs.readdirSync(`./Photo`).forEach(file => {
getCsv(`${(__dirname)}/Photo/${file}`);
})
function getCsv(OurFile){
var promise = new Promises(function (resolve, reject) {
var error;
Jimp.read(OurFile, function (err, lenna) {
if (err) {
error = err;
reject(error);
}
lenna.write(OurFile);
})
if (!error) {
resolve(OurFile);
} else {
reject("Error!");
}
});
promise.then(function (data) {
return new Promises(function (resolve, reject) {
var image = new Jimp(data, function (err, image) {
var w = image.bitmap.width;
var h = image.bitmap.height;
resolve(JSON.stringify({
name : data,
width : w,
height : h
}))
})
})
}).then(function (data) {
return new Promises(function (resolve, reject) {
var objectValue = JSON.parse(data);
var width = objectValue['width'];
var name = objectValue['name'];
var jpegData = fs.readFileSync(name);
var rawImageData = jpeg.decode(jpegData, true); // return as Uint8Array
var typedarray = rawImageData.data;
//console.log(typedarray)
var length = typedarray.length;
var n = [];
var i = 0;
for (l = length + 1; (i + width) < l; i += width) {
n.push(typedarray.slice(i, i + width));
}
resolve(n);
})
}).then(function (data) {
return new Promises(function (resolve, reject) {
var d = exportToCsv(data);
fs.writeFile(`${OurFile.split(".")[0]}.csv`, d, function (err) {
if (err) throw err;
console.log('Saved!');
});
});
})
}
function exportToCsv(rows) {
var processRow = function (row) {
var finalVal = '';
for (var j = 0; j < row.length; j++) {
var innerValue = row[j] === null ? '' : row[j].toString();
if (row[j] instanceof Date) {
innerValue = row[j].toLocaleString();
};
var result = innerValue.replace(/"/g, '""');
if (result.search(/("|;|\n)/g) >= 0)
result = '"' + result + '"';
if (j > 0)
finalVal += ';';
finalVal += result;
}
return finalVal + '\n';
};
var csvFile = '';
for (var i = 0; i < rows.length; i++) {
csvFile += processRow(rows[i]);
}
return csvFile;
}
我使用Promises,因为它是处理这些东西逐行运行的唯一方法。
所以,首先我将图像重写为jpeg格式,然后我将其宽度用于将来的解析,然后我以Uint8ClampedArray格式获取我的ImageData,最后将其写入csv文件。
答案 0 :(得分:0)
试试这个,
var fs = require('fs');
var jpeg = require('jpeg-js');
var Jimp = require("jimp");
function scanDir(folder, files = []) {
var me = this,
stats,
fileContents = fs.readdirSync(folder);
fileContents.forEach(function(filename) {
var absFilename = folder + '/' + filename;
stats = fs.lstatSync(absFilename);
if(stats.isDirectory(absFilename)) {
me.scanDir(absFilename, files);
} else {
files.push(absFilename);
}
});
return files;
}
function getImageInfos(filename) {
return new Promise((resolve, reject) => {
Jimp.read(filename, (err, image) => {
if(err) {
reject(err);
} else {
resolve({
name: filename,
width: image.bitmap.width,
height: image.bitmap.height
});
}
});
});
}
function getUInt8Array(file) {
let typed,
filename = file.name,
width = file.width;
file.uint = [];
return new Promise((resolve, reject) => {
fs.readFile(filename, (err, data) => {
if(err) {
reject(err);
} else {
typed = jpeg.decode(data, true).data;
for(let c = 0; c < typed.length; c += width) {
file.uint.push(typed.slice(c, c + width).join(' '));
}
file.uint = file.uint.join('\n');
resolve(file);
}
});
});
}
function saveIntoCsvFile(file) {
let filename = file.name.split('.').slice(0, -1).join('.') + '.csv',
content = [
'"filename","width","height","content"',
'"' + Object.keys(file).map((k) => file[k]).join('","') + '"'
].join('\n');
return new Promise((resolve, reject) => {
fs.writeFile(filename, content, (err) => {
if(err) {
reject(err);
} else {
resolve();
}
});
});
}
let validExtensions = [
'jpg',
'jpeg'
];
// scan images and filter files if not images
let files = scanDir('./Photo').filter((file) => {
let extension = file.split('.').pop();
return (validExtensions.indexOf(extension) >= 0);
});
let promises = [];
// for each filename get size info and
// get uint8arr data and finally
// save content in csv file
for(let file of files) {
promises.push(
getImageInfos(file)
.then(getUInt8Array)
.then(saveIntoCsvFile)
);
}
// resolve all promises
Promise.all(promises)
.then(() => {
console.log('end');
})
.catch((err) => {
console.error(err);
});