Node.js中使用Resemble.js获取外部图片报错:读取输入流错误
解决Resemble.js对比远程URL图片时的「error while reading from input stream」错误
我来帮你搞定这个问题~你遇到的这个报错,核心原因是Resemble.js本身并不支持直接传入远程URL进行图片对比——它默认只认本地文件路径或者Node.js Buffer对象。当你直接把URL丢给resemble()方法时,它会尝试像读取本地文件一样去解析这个URL,这肯定会触发流读取错误。
解决方案:先下载远程图片为Buffer再对比
我们只需要先把远程图片下载到本地内存(转为Buffer),再传给Resemble.js处理就行。下面是具体的实现步骤:
1. 推荐替换依赖(可选但更稳妥)
你代码里用的request库已经停止维护了,我推荐换成axios,先安装:
npm install axios
2. 调整后的完整代码
我把关键修改都标出来了,直接用就行:
const resemble = require('resemblejs'); const fs = require("mz/fs"); const axios = require('axios'); // 你的远程图片URL const remoteImg1 = "https://static-cdn.jtvnw.net/previews-ttv/live_user_combatgo-640x360.jpg"; const remoteImg2 = "https://static-cdn.jtvnw.net/previews-ttv/live_user_combatgo-640x360.jpg"; // 封装一个下载远程图片的工具函数 async function fetchImageAsBuffer(url) { try { // 关键:请求时指定返回二进制数组,转成Buffer const response = await axios.get(url, { responseType: 'arraybuffer', // 如果遇到防盗链,可以加个请求头模拟浏览器 headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' } }); return Buffer.from(response.data, 'binary'); } catch (err) { console.error('下载图片失败:', err.message); throw err; } } async function getDiff() { const options = { output: { errorColor: { red: 255, green: 0, blue: 255 }, errorType: 'movement', transparency: 0.3, largeImageThreshold: 1200, useCrossOrigin: false, outputDiff: true }, scaleToSameSize: true, ignore: ['nothing', 'less', 'antialiasing', 'colors', 'alpha'], }; try { // 先把两张远程图片转成Buffer const imgBuf1 = await fetchImageAsBuffer(remoteImg1); const imgBuf2 = await fetchImageAsBuffer(remoteImg2); // 用Buffer做对比,用Promise封装回调让代码更整洁 const diffData = await new Promise((resolve) => { resemble(imgBuf1) .compareTo(imgBuf2) .setOptions(options) .onComplete(resolve); }); console.log('对比结果:', diffData); // 保存差异图到本地 await fs.writeFile('./output.png', diffData.getBuffer()); console.log('差异图已保存到 ./output.png'); } catch (err) { console.error('对比过程出错:', err.message); } } getDiff();
关键修改说明
- 新增
fetchImageAsBuffer函数:专门处理远程图片的下载,通过axios获取二进制数据并转为Buffer,还加了可选的请求头应对防盗链。 - 用Buffer替代URL传入Resemble.js:现在对比的是内存中的Buffer对象,完全符合Resemble.js的预期输入类型。
- Promise封装回调:把Resemble.js的回调式API改成Promise风格,配合
await让代码逻辑更清晰,避免回调嵌套。
额外小提示
- 如果你的环境需要代理才能访问外网,记得给
axios配置代理参数。 - 要是遇到图片无法下载的情况,先手动访问一下URL确认是否能正常打开,排除权限或者网络问题。
内容的提问来源于stack exchange,提问作者Nikse
相关产品推荐
相关产品推荐

