【问题标题】:NodeJS peaking at 6Gb when manipulating images with Jimp使用 Jimp 处理图像时,NodeJS 达到 6Gb 的峰值
【发布时间】:2021-10-11 22:53:27
【问题描述】:

我需要在像素尺度上编辑 34 000 张照片,所以我编写了一个程序,如果图像中的像素超过特定的 RBG 值(240、240、240),则替换它们,基本上我只想隔离白色像素并将其他所有内容设置为黑色。这是我的代码:

const jimp = require('jimp')
var fs = require('fs');
const PNG = require('pngjs').PNG;


const frames = fs.readdirSync("./out/")
for (let i = 0; i < frames.length; i++) {
    function work(frames, i) {
        if (frames[i] !== ".DS_Store") { 
            jimp.read('./out/' + frames[i], (err, image) => {
                const bitmap = new Uint8ClampedArray(image.bitmap.data)
                let texterHighlit = 240
                let nextD = 4;
                let items = [];
                for (i = 0; i < bitmap.length + 1; i++) {
                    if (i === nextD) {
                        if (bitmap[i - 4] > texterHighlit && bitmap[i - 3] > texterHighlit && bitmap[i - 2] > texterHighlit) {
                            items.push(255)
                            items.push(255)
                            items.push(255)
                            items.push(255)
                        } else {
                            items.push(0)
                            items.push(0)
                            items.push(0)
                            items.push(255)
                        }
                        nextD = nextD + 4;
                    }
                }

                var img_width = image.bitmap.width;
                var img_height = image.bitmap.height;
                var img_data = Uint8ClampedArray.from(items);
                var img_png = new PNG({ width: img_width, height: img_height })
                img_png.data = Buffer.from(img_data);
                img_png.pack().pipe(fs.createWriteStream("./out/" + frames[i])) 
                return "done";

            })
        }
    }
    work(frames, i)

}

现在,这适用于一些图像,但在我提到的 34 000 个图像文件夹等大型数据集上使用它时问题开始出现。

作为参考,我在 CentOS8 上使用 PM2 和 --no-autorestart 标志运行此代码。当不使用 PM2 而只使用node &lt;file&gt; 时,进程被杀死并在控制台中输出“被杀死”,它不会显示“内存不足”。我已经尝试调试了很长一段时间,但没有办法阻止这种情况,我尝试不使用 Jimp,而是使用名为 image-pixels 的包,它产生了相同的结果。

有没有办法防止这种情况发生,或者我必须在较小的文件夹上手动执行此操作(例如每个 1000 张图像)?

【问题讨论】:

    标签: javascript node.js jimp


    【解决方案1】:

    好的,所以异步 正确完成 是最后的答案,感谢 NeonSurvivor#2046 在 Discord 上给我的答案!

    const jimp = require('jimp')
    var fs = require('fs');
    
    (async() => {
        async function work(frame) {
        if (frame === '.DS_Store') return;
        const image = await jimp.read('./out/' + frame);
        const texterHighlit = 240;
        image.scan(0, 0, image.bitmap.width, image.bitmap.height, (x, y, idx) => {
            const { data } = image.bitmap;
            data[idx] = data[idx + 1] = data[idx + 2] = 255 *  [0, 1, 2].every(offset => data[idx + offset] > texterHighlit);
            data[idx + 3] = 255;
        });
        image.write('./out/' + frame);
        return 'done';
    }
    
    for (const frame of fs.readdirSync('./out/')) {
        await work(frame);
        await new Promise(res => setTimeout(res, 500));
    }
    })()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-14
      • 2020-01-16
      • 1970-01-01
      • 2019-02-23
      • 2018-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多