2

我通过该方法计算的分数值对图像进行排序,该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。有人可以解释这里实际发生的事情以及如何解决这个问题吗?

4

1 回答 1

1

幸运的是,Facebook 的某个人 (Iulian Popescu) 告诉我,files.forEach不等待承诺完成,因此他们被阻止了。我设法通过添加更多承诺来解决这种情况。例如,promise 之一读取所有数据。在读取所有数据并将其保存在一些全局变量中之后,其他 Promise 将以正确的顺序执行。如果您想真正看到我正在谈论的解决方案的实现,可以在我的 GitHub 上查看:https ://github.com/tomaAlex/darkImageClassifier/blob/master/index.js

于 2020-07-13T11:16:36.930 回答