我通过该方法计算的分数值对图像进行排序,该getImageScore
方法包含在一个承诺中,因为加载它必须使用的像素需要相当长的时间。我观察到承诺被阻止,永远不会完成。这是最初的整个程序:
const fs = require('fs');
const { resolve } = require('path');
const { reject } = require('q');
const { Console } = require('console');
const gm = require('gm').subClass({imageMagick: true});
const PNG = require("pngjs").PNG;
let pathToFolder = '/home/eugen/Pictures/wallpapers1';
let pathToImage = '';
let promiseImageScore = new Promise((resolve, reject) => {
getImageScore(resolve, reject);
});
function getImageScore(resolve, reject) {
console.log('entered this promise....');
let img = gm(pathToImage);
// Get the PNG buffer
img.toBuffer("PNG", (err, buff) => {
if (err) return reject(err);
console.log('got buffer...');
// Get the image size
img.size((err, size) => {
if (err) {
console.log(err);
return reject(err);
}
console.log('got image size...');
// Parse the PNG buffer
let str = new PNG();
str.end(buff);
// After it's parsed...
str.on("parsed", buffer => {
// Get the pixels from the image
let idx, score = 0, rgb = {r: 0, g: 0, b: 0};
for (let y = 0; y < size.height; y++)
for (let x = 0; x < size.width; x++) {
idx = (size.width * y + x) << 2;
rgb.r = buffer[idx];
rgb.g = buffer[idx + 1];
rgb.b = buffer[idx + 2];
score += (rgb.r + rgb.g + rgb.b) / 765;
}
console.log('one promise finished...');
return resolve(score / (size.height * size.width));
});
str.on("error", e => {
return reject(e);
});
});
});
}
// see which images are to be found in the specificd directory
fs.readdir(pathToFolder, function (err, files) {
if (err) return console.log('Unable to scan directory: ' + err);
console.log('files in directory:\n');
files.forEach(function (file) {
pathToImage = pathToFolder + '/' + file;
//showImageScore();
promiseImageScore
.then(imageScore => {
console.log(file + ' has a score of ' + imageScore);
})
.catch(e => {
throw e;
})
});
});
运行上面的代码会得到这个输出:
entered this promise....
files in directory:
got buffer...
记录got buffer
消息后,程序将继续运行......我看到,通过修改我吸引图像的方式,我最终会got image size
在控制台中获得日志。因此,这是我修改getImageScore
方法的方式:
function getImageScore(resolve, reject) {
console.log('entered this promise....');
//let img = gm(pathToImage);
// Get the PNG buffer
//img.toBuffer("PNG", (err, buff) => {
gm(pathToImage).toBuffer("PNG", (err, buff) => {
if (err) return reject(err);
console.log('got buffer...');
// Get the image size
//img.size((err, size) => {
gm(pathToImage).size((err, size) => {
if (err) {
console.log(err);
return reject(err);
}
console.log('got image size...');
// Parse the PNG buffer
let str = new PNG();
console.log('created str...');
str.end(buff);
console.log('got str...');
// After it's parsed...
str.on("parsed", buffer => {
// Get the pixels from the image
let idx, score = 0, rgb = {r: 0, g: 0, b: 0};
for (let y = 0; y < size.height; y++)
for (let x = 0; x < size.width; x++) {
idx = (size.width * y + x) << 2;
rgb.r = buffer[idx];
rgb.g = buffer[idx + 1];
rgb.b = buffer[idx + 2];
score += (rgb.r + rgb.g + rgb.b) / 765;
}
console.log('one promised finished...');
return resolve(score / (size.height * size.width));
});
str.on("error", e => {
return reject(e);
});
});
});
}
进行这些更改后,我在控制台中得到以下输出:
entered this promise....
files in directory:
got buffer...
got image size...
created str...
events.js:174
throw er; // Unhandled 'error' event
^
Error: Invalid file signature
at module.exports.Parser._parseSignature (/home/eugen/Documents/scripts/sort_pictures_by_brightness/node_modules/pngjs/lib/parser.js:53:18)
at module.exports.ChunkStream._processRead (/home/eugen/Documents/scripts/sort_pictures_by_brightness/node_modules/pngjs/lib/chunkstream.js:174:13)
at module.exports.ChunkStream._process (/home/eugen/Documents/scripts/sort_pictures_by_brightness/node_modules/pngjs/lib/chunkstream.js:193:14)
at module.exports.ChunkStream.write (/home/eugen/Documents/scripts/sort_pictures_by_brightness/node_modules/pngjs/lib/chunkstream.js:61:8)
at module.exports.ChunkStream.end (/home/eugen/Documents/scripts/sort_pictures_by_brightness/node_modules/pngjs/lib/chunkstream.js:74:10)
at exports.PNG.PNG.end (/home/eugen/Documents/scripts/sort_pictures_by_brightness/node_modules/pngjs/lib/png.js:98:16)
at gm.size (/home/eugen/Documents/scripts/sort_pictures_by_brightness/index.js:34:11)
at gm.emit (events.js:198:13)
at gm.<anonymous> (/home/eugen/Documents/scripts/sort_pictures_by_brightness/node_modules/gm/lib/getters.js:82:14)
at cb (/home/eugen/Documents/scripts/sort_pictures_by_brightness/node_modules/gm/lib/command.js:322:16)
Emitted 'error' event at:
at module.exports.emit (events.js:198:13)
at module.exports.ChunkStream._process (/home/eugen/Documents/scripts/sort_pictures_by_brightness/node_modules/pngjs/lib/chunkstream.js:207:10)
at module.exports.ChunkStream.write (/home/eugen/Documents/scripts/sort_pictures_by_brightness/node_modules/pngjs/lib/chunkstream.js:61:8)
[... lines matching original stack trace ...]
at cb (/home/eugen/Documents/scripts/sort_pictures_by_brightness/node_modules/gm/lib/command.js:322:16)
at ChildProcess.onExit (/home/eugen/Documents/scripts/sort_pictures_by_brightness/node_modules/gm/lib/command.js:305:9)
从输出来看,我们可以说该str.end(buff);
行存在某种问题,因为程序从不输出got str
日志。在对方法进行更改之前,似乎不存在此问题getImageScore
。首先,我真的不明白为什么在本地对象中加载图像会是一个会导致代码意外运行的问题。其次,修改图像的加载方式不应改变库中的end
方法pngjs
。有人可以解释这里实际发生的事情以及如何解决这个问题吗?