NodeJS GM无法读取ASP.NET下载的JPEG文件,报解码委托缺失错误
问题描述
从ASP.NET网站下载的JPEG文件底部被附加了随机HTML内容,GIMP、Photoshop等软件可正常读取,但使用Node.js的GM库读取或处理时抛出错误,调整图片尺寸操作也失败。曾尝试用buffer-split移除文件中的<!DOCTYPE部分,但问题仍未解决。
报错信息
Error: Command failed: gm identify: No decode delegate for this image format (/tmp/gmIc3ey2). gm identify: Request did not return an image. at ChildProcess.onExit (/home/novelty/Desktop/api_service/node_modules/gm/lib/command.js:318:17) at ChildProcess.emit (node:events:511:28) at maybeClose (node:internal/child_process:1098:16) at ChildProcess._handle.onexit (node:internal/child_process:304:5) { code: 1, signal: null } Error: Command failed: gm identify: No decode delegate for this image format (/tmp/gmKoGJsp). gm identify: Request did not return an image. at ChildProcess.onExit (/home/novelty/Desktop/api_service/node_modules/gm/lib/command.js:318:17) at ChildProcess.emit (node:events:511:28) at maybeClose (node:internal/child_process:1098:16) at ChildProcess._handle.onexit (node:internal/child_process:304:5) { code: 1, signal: null }
示例代码
import gm from 'gm' const imageData = await (await fetch('https://cdn.discordapp.com/attachments/1113934560254754897/1115865687710236823/1.jpeg1')).arrayBuffer() gm(Buffer.from(imageData)) .identify( (error, info) => console.log(info) )
解决方案
GM依赖的ImageMagick对文件格式校验更严格,而GIMP等工具容错性更强。解决核心是移除JPEG结束标记后的所有冗余内容,而非仅删除<!DOCTYPE片段——因为冗余数据可能早于HTML开头,或截断位置不准确。
方法1:手动截断到JPEG结束标记
JPEG标准结束标记为十六进制FFD9,遍历Buffer找到该标记位置后截断即可:
import gm from 'gm' const imageData = await (await fetch('https://cdn.discordapp.com/attachments/1113934560254754897/1115865687710236823/1.jpeg1')).arrayBuffer() const buffer = Buffer.from(imageData) // 查找JPEG结束标记FFD9 const eoiMarker = Buffer.from([0xFF, 0xD9]) const eoiIndex = buffer.indexOf(eoiMarker) if (eoiIndex !== -1) { // 截断至结束标记末尾 const cleanedBuffer = buffer.slice(0, eoiIndex + 2) gm(cleanedBuffer) .identify((error, info) => { error ? console.error(error) : console.log(info) }) } else { console.error('未找到JPEG结束标记') }
方法2:用JPEG专用库修复
使用jpeg-js库解码并重新编码图片,自动过滤冗余内容后再交给GM处理:
import gm from 'gm' import { decode, encode } from 'jpeg-js' const imageData = await (await fetch('https://cdn.discordapp.com/attachments/1113934560254754897/1115865687710236823/1.jpeg1')).arrayBuffer() const buffer = Buffer.from(imageData) // 解码时自动忽略末尾无效数据 const jpegData = decode(buffer) // 重新编码为标准JPEG格式 const cleanedBuffer = encode(jpegData).data gm(cleanedBuffer) .identify((error, info) => { error ? console.error(error) : console.log(info) })
方法3:调整ImageMagick容错参数(不推荐)
ImageMagick支持通过参数提高容错性,可通过GM传递该参数,但此方法兼容性不稳定:
gm(Buffer.from(imageData)) .options({ imageMagick: true }) .define('jpeg:ignore-warnings') .identify((error, info) => console.log(info))
内容的提问来源于stack exchange,提问作者devishdude
相关产品推荐
相关产品推荐

