You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js中Jimp循环执行时随机抛出Could not find MIME for Buffer <null>错误

问题原因分析
  • 异步操作顺序混乱:takeScreenshot里的image.write('test-screenshot.png')是异步方法,但你在调用它之后立刻打印"Saved...",实际这时候文件还没写完。而convertScreenshot紧接着执行,去读取这个可能还未写入完成的文件,就会出现读入空Buffer的情况,触发Could not find MIME for Buffer <null>错误。
  • 循环执行的叠加问题:每2秒一次的foo()调用会重复触发读写操作,旧的读写操作还没完成,新的又开始,进一步加剧了文件资源的竞争,导致错误随机出现。
修复方案

方案1:严格控制异步操作顺序

把takeScreenshot包装成Promise,确保文件写入完成后再执行转换操作:

const Jimp = require("jimp");

function takeScreenshot() {
    // 声明变量避免全局污染
    const x=35, y=11, width=180, height=17;
    const img = robot.screen.capture(x, y, width, height).image;
    
    return new Promise((resolve, reject) => {
        new Jimp({data: img, width, height}, (err, image) => {
            if (err) return reject(err);
            // 使用Jimp的writeAsync方法返回Promise
            image.writeAsync('test-screenshot.png')
                .then(() => {
                    console.log("Saved...");
                    resolve();
                })
                .catch(reject);
        });    
    });
}
  
async function convertScreenshot() {
    try {
        console.log("converting...");
        const image = await Jimp.read('test-screenshot.png');
        await image.contrast(0.8).writeAsync('test-contrastScreenshot.png');
    } catch(error) {
        console.log(error);
    }
}

async function foo() {
    // 先等待截图保存完成,再执行转换
    await takeScreenshot();
    await convertScreenshot();
    setTimeout(foo, 2000);
}
foo();

方案2:避免文件覆盖(可选)

给每个截图文件添加时间戳后缀,彻底避免读写冲突:

const Jimp = require("jimp");

function takeScreenshot() {
    const timestamp = Date.now();
    const fileName = `test-screenshot-${timestamp}.png`;
    const x=35, y=11, width=180, height=17;
    const img = robot.screen.capture(x, y, width, height).image;
    
    return new Promise((resolve, reject) => {
        new Jimp({data: img, width, height}, (err, image) => {
            if (err) return reject(err);
            image.writeAsync(fileName)
                .then(() => {
                    console.log(`Saved ${fileName}...`);
                    resolve(fileName);
                })
                .catch(reject);
        });    
    });
}
  
async function convertScreenshot(fileName) {
    try {
        console.log("converting...");
        const image = await Jimp.read(fileName);
        const outputName = fileName.replace('.png', '-contrast.png');
        await image.contrast(0.8).writeAsync(outputName);
    } catch(error) {
        console.log(error);
    }
}

async function foo() {
    const fileName = await takeScreenshot();
    await convertScreenshot(fileName);
    setTimeout(foo, 2000);
}
foo();
额外注意事项
  • 变量必须用const/let声明,原代码中x、y等变量未声明会成为全局变量,可能引发其他隐性问题。
  • 优先使用Jimp提供的writeAsync这类返回Promise的方法,比回调写法更易维护和控制流程。

内容的提问来源于stack exchange,提问作者Genesis1337

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 04:05:55