首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Jimp处理图像时,NodeJS峰值为6Gb

使用Jimp处理图像时,NodeJS峰值为6Gb
EN

Stack Overflow用户
提问于 2021-08-07 11:09:13
回答 1查看 232关注 0票数 1

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

代码语言:javascript
复制
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)

}

现在,这对于一些图像非常有用,但是当在我提到的34000图像文件夹这样的大型数据集中使用它时,问题就开始出现了。

作为参考,我在CentOS8上使用PM2和--no-autorestart标志运行这段代码。当不使用PM2而只使用node <file>时,进程会在控制台中被终止并输出“挂起”,它不会显示“内存耗尽”的情况。我已经尝试调试了很长一段时间,但是没有找到阻止这种情况的方法,我尝试不使用Jimp,而是使用一个名为像象素的包,它产生了相同的结果。

是否有办法防止这种情况发生,或者我是否必须在较小的文件夹(例如,每个1000张图像)上手动完成?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-08-07 15:21:48

好的,所以异步做的正确是最终的答案,归功于NeonSurvivor#2046给我的这个不和谐的答案!

代码语言:javascript
复制
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));
}
})()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68691843

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档