ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

用 Node.js 给 PNG 商品图做一道文件检查

用 Node.js 给 PNG 商品图做一道文件检查 图片制作完成以后运营仍可能收到尺寸过小、体积过大甚至扩展名与内容不相符的文件。本文实现一道本地 PNG 预检读取文件签名和 IHDR 宽高按项目配置输出告警不修改原图不上传图片。它适合接在素材导出之后。例如从 Picset 或其他图像工具导出的文件可以先进入这道检查这不需要假设这些工具提供 API也不是对其输出质量的评价。[1] JPEG、WebP 等格式不在这段代码的识别范围内。先划清这段检查的边界PNG 以固定签名开始首个数据块为 IHDR其中包含宽、高等信息。[2] 根据这些字段可以判断基本头部是否符合预期以及尺寸是否达到当前配置。但读取头部不等于成功解码。下面代码不校验所有数据块的 CRC也不检查图像数据是否完整所以不应把返回结果命名为“图片安全”或“可上架”。输出只说明这一轮文件预检看到了什么。图像真正打开后的内容、商品准确性和目标平台要求还需要其他检查。读取有限字节不把大文件全部装进内存代码使用 Node.js 内置模块只读取前面一小段头部。下面的尺寸与体积阈值均为演示配置不是任何电商平台的统一要求。正式使用时应按真实版位填写。const fs require(‘node:fs/promises’);const path require(‘node:path’);const SIGNATURE Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]);const rules { minWidth: 1200, minHeight: 1200,maxBytes: 5 * 1024 * 1024 };function inspectHeader(head, bytes, config) {if (head.length 33) throw new Error(‘PNG 头部不足’);if (!head.subarray(0, 8).equals(SIGNATURE))throw new Error(‘文件签名不是 PNG’);if (head.readUInt32BE(8) ! 13 ||head.toString(‘ascii’, 12, 16) ! ‘IHDR’)throw new Error(‘首个块不是预期的 IHDR’);const width head.readUInt32BE(16);const height head.readUInt32BE(20);if (!width || !height || width 0x7fffffff ||height 0x7fffffff) throw new Error(‘宽高超出 PNG 范围’);const warnings [];if (width config.minWidth || height config.minHeight)warnings.push(‘宽高低于项目阈值’);if (bytes config.maxBytes) warnings.push(‘体积超过项目阈值’);return { width, height, bytes, warnings };}async function inspectFile(file) {const handle await fs.open(file, ‘r’);try {const stat await handle.stat();if (!stat.isFile()) throw new Error(‘不是普通文件’);const head Buffer.alloc(33);const { bytesRead } await handle.read(head, 0, 33, 0);return inspectHeader(head.subarray(0, bytesRead), stat.size, rules);} finally { await handle.close(); }}async function scan(dir) {const entries await fs.readdir(dir, { withFileTypes: true });for (const entry of entries) {if (!entry.isFile() || !/.png$/i.test(entry.name)) continue;try { console.log(JSON.stringify({ file: entry.name,…await inspectFile(path.join(dir, entry.name)) })); }catch (error) { console.log(JSON.stringify({file: entry.name, error: error.message })); }}}module.exports { inspectHeader, inspectFile, scan };if (require.main module)scan(process.argv[2] || ‘.’).catch(e {console.error(e.message); process.exitCode 1;});保存为 png-preflight.cjs执行 node png-preflight.cjs ./images。每个被扫描的文件输出一行 JSON。没有告警意味着“没有违反这份配置”不是达到了全部平台要求不支持的扩展名会被跳过代码也不会递归扫描子目录或跟随目录中的符号链接。让失败路径也能复查测试时不能只用一张正常图片。应包含短文件、改了扩展名的非 PNG、错误 IHDR、零宽高以及尺寸或体积触发告警的输入。文章包附有使用合成头部的单元测试并额外对本批配图运行预检。合成输入只能验证这些分支不能代替完整图像解码测试。这里还有一个业务上的误区为了消除“宽高过小”告警而直接放大图片不会凭空获得原图没有记录的商品细节。程序负责发现配置差距是否补拍、重新导出或者调整版位应由素材用途决定。文件指标与商品信息质量要分开看。线前再给文件记录加上 SKU、用途和版本预检结果才方便回到具体图片。这个小脚本适合承担导出后的第一道筛选不适合单独承担发布审核。参考资料[1] Picset 产品介绍国际站提示升级为 Picell AI本文不涉及其 API。[2] W3CPNG Specification文件结构与 IHDR
返回列表