☰
在 Node.js 中一键移除图片背景:@imgly/background-removal-node 完整实战指南
2026/10/15 19:04:03 网站建设 项目流程
  • 计算机视觉
  • 图像处理
  • AI 应用

【免费下载链接】background-removal-js

Remove backgrounds from images directly in the browser environment with ease and no additional costs or privacy concerns. Explore an interactive demo.

项目地址:https://gitcode.com/gh_mirrors/ba/background-removal-js
点击查看免费下载

导读

本指南以@imgly/background-removal-node的官方文档(packages/node/README.md)为骨架,结合仓库源码逐层剖析这个能够在 Node.js 环境中直接完成人像/物体抠图的 npm 包:从安装、基础调用到Config全量配置、模型体积权衡、下载进度监控、自定义资源托管(Custom Asset Serving)与 CORS 处理,并深入源码解释一次抠图调用的完整链路(配置校验 → 模型分块加载 → ONNX 推理 → 双线性插值 → 编码输出)。读完本文,你将能够在自己的 Node.js 项目中独立接入背景移除能力,并理解其底层实现原理与生产环境部署要点。

一、项目概览:浏览器级抠图能力下沉到 Node.js

@imgly/background-removal-node是 IMG.LY 开源项目 background-removal-js 的 Node.js 发行包(packages/node/package.json 中name字段),它把原本面向浏览器的背景移除能力带到了服务端/命令行环境。其核心特征包括:

  • 零 API 成本、无隐私顾虑:推理完全在本地(Node.js 进程内)完成,图片数据不需要上传到任何第三方服务;
  • ONNX 模型驱动:采用 ONNX 格式的神经网络模型(ISNet 系列),由 IMG.LY 托管发布,随包分发或可自托管;
  • 与 CE.SDK 生态无缝衔接:可轻松集成到基于 IMG.LY CreativeEditor SDK 的创意应用中;
  • 丰富的导出能力:支持 PNG / JPEG / WebP / 原始 rgba8 / 原始 alpha8 等多种输出格式与前景、背景、蒙版等多种输出语义(见 CHANGELOG 1.2.0–1.4.0 记录)。

根据 packages/node/CHANGELOG.md 与 README 的 News 时间线:2023 年 9 月 12 日首次发布 Node.js 版本;2023 年 11 月先后加入foreground/background/mask导出类型与webp、jpeg格式支持、原始rgba8格式;2025 年 7 月 18 日升级到稳定版 ONNX Runtime 1.21.0(packages/node/package.json 中onnxruntime-node: 1.21.0与之一致)。

二、安装

通过 npm 安装即可:

npm install @imgly/background-removal-node

仓库内同时提供了可直接运行的示例工程 packages/node-examples(脚本start: node src/example_001.cjs)以及端到端冒烟测试工程 packages/node-e2e,可用于快速验证安装与调用。

三、基础用法:removeBackground

官方文档给出的最小可用代码如下(TypeScript 与 CommonJS 两种导入方式均可):

import { removeBackground } from "@imgly/background-removal-node"; // const { removeBackground } = require("@imgly/background-removal-node"); let image_src: ImageData | ArrayBuffer | Uint8Array | Blob | URL | string = ...; removeBackground(image_src).then((blob: Blob) => { // 结果是以 PNG 编码的 Blob,可转换为 URL 作为 HTMLImage.src 使用 const url = URL.createObjectURL(blob); });

输入类型:从源码看,packages/node/src/utils.ts 中定义的ImageSource实际支持ArrayBuffer | Uint8Array | Blob | URL | string | NdArray<Uint8Array>六类输入。imageSourceToImageData会做如下归一化(packages/node/src/utils.ts):

  • string:按file://${process.cwd()}/作为基准解析为绝对 URI(因此可以直接传本地文件路径或远程 URL 字符串);
  • URL:通过loadFromURI拉取后转成Blob(支持http:、https:、file:三种协议,见 packages/node/src/resource.ts);
  • ArrayBuffer/ 各类 TypedArray 视图:包装成Blob;
  • Blob:交给 sharp 解码成 RGBA 像素张量。

返回值:Promise<Blob>,默认是 PNG 编码。可将它直接用于URL.createObjectURL、写入文件或继续参与后续图像管线。

首次运行的耗时说明:README 明确指出,首次运行时 wasm 与 onnx 模型文件会被加载,耗时与带宽/磁盘相关,因此第一次调用明显慢于后续调用。在 Node 端,这一缓存由memoize实现——packages/node/src/index.ts 中以配置的 JSON 序列化为键对initInference做了记忆化,相同配置下的后续调用直接复用已创建的 ONNX 推理会话,无需重新加载模型。

四、Config 全量配置详解

该库开箱即用,无需任何配置;但官方文档提供了以下可选参数,用于精细控制行为:

type Config = { publicPath: string; // 模型与 wasm 文件的公共路径。默认:'file://${path.resolve(`node_modules/${pkg.name}/dist/`)}/' debug: bool; // 是否输出有用的 console.log 调试信息 model: 'small' | 'medium'; // 使用的模型(默认 "medium") output: { format: 'image/png' | 'image/jpeg' | 'image/webp' | 'image/x-rgba8'; // 输出格式(默认 "image/png") quality: number; // 质量(默认 0.8) type: 'foreground' | 'background' | 'mask'; // 输出类型(默认 "foreground") }; };

结合当前仓库源码,有几点需要补充说明(避免照搬文档导致与现版本脱节):

  1. output.type已在 1.3.0 移除:根据 packages/node/CHANGELOG.md 1.3.0 条目“Removed: Configuration options to specify if background, foreground or mask is exported”,该选项已被拆分为独立的removeBackground/removeForeground/segmentForeground三个 API。当前 packages/node/src/schema.ts 中output只包含format与quality两个字段。
  2. model的取值映射:packages/node/src/schema.ts 使用 zod 的preprocess做归一化:'small'→isnet_quint8,'medium'→isnet_fp16,'large'→isnet,最终枚举为'isnet' | 'isnet_fp16' | 'isnet_quint8',默认'medium'。仓库 bundle/models 目录下恰好对应isnet、isnet_fp16、isnet_quint8三个模型目录,印证了模型家族的构成。
  3. format实际还支持image/x-alpha8:schema 枚举为'image/png' | 'image/jpeg' | 'image/webp' | 'image/x-rgba8' | 'image/x-alpha8',其中x-alpha8用于导出单通道 alpha 蒙版(1.3.0 新增,配合segmentForeground使用)。
  4. 额外的 schema 字段:当前 packages/node/src/schema.ts 中还定义了fetchArgs(透传给 fetch 的参数)与proxyToWorker(是否代理到 Web Worker 推理;该字段在 Web 包中生效,Node 包 schema 中保留但无对应 Worker 运行时)。
  5. publicPath模板与校验:默认值为`file://${path.resolve(`node_modules/${pkg.name}/dist/`)}/`,并支持${PACKAGE_NAME}、${PACKAGE_VERSION}占位符替换;最终值必须通过isURI校验,否则报错String must be a valid uri。

4.1 下载体积与质量的权衡

README 对模型的体积/质量给出了官方说明:

  • small(约 40 MB):体积最小的量化模型(quantized model),大多数场景下表现良好,但偶尔会出现伪影(artifacts);
  • medium(约 80 MB):默认模型,质量与体积的平衡之选。

配合源码可知:small 对应isnet_quint8(8-bit 量化),medium 对应isnet_fp16(半精度),而'large'(isnet)则是仓库中提供的最大尺寸模型。你可以根据“带宽/磁盘成本”与“抠图精度”的实际诉求在三者间切换,例如:

let config: Config = { model: 'small' // 或 'medium' / 'large' / 'isnet_fp16' / 'isnet_quint8' / 'isnet' };

五、下载进度监控

由于模型文件体积较大(数十 MB 级别),官方提供了progress回调以便在首次加载时展示进度:

let config: Config = { progress: (key, current, total) => { console.log(`Downloading ${key}: ${current} of ${total}`); } };

从源码看,该回调在两条路径中被触发(packages/node/src/resource.ts 与 packages/node/src/inference.ts):

  • 资源下载阶段:键为fetch:${key}(例如fetch:/models/isnet_fp16),current为已下载字节累计、total为资源总大小;
  • 推理计算阶段:键为compute:inference,从(0,1)推进到(1,1)。

仓库示例 packages/node-examples/src/example_001.cjs 展示了实际用法——按:拆分 key 为类型与子类型,并输出百分比:

const config = { progress: (key, current, total) => { const [type, subtype] = key.split(':'); console.log(`${type} ${subtype} ${((current / total) * 100).toFixed(0)}%`); } };

六、自定义资源托管(Custom Asset Serving)

README 明确建议:默认情况下 wasm 与 onnx 模型文件托管在 IMG.LY 的服务器上;生产环境应将它们托管到自己的服务器/本地路径。操作分两步:

第一步:把dist/下所有.wasm与.onnx文件拷贝到你的公共目录$PUBLIC_PATH:

cp node_modules/@imgly/background-removal-node/dist/*.* $PUBLIC_PATH

第二步:在配置中指定publicPath(支持本地file://路径或远程https://路径):

import { removeBackground, Config } from "@imgly/background-removal-node"; const public_path = "file://${ASSET_PATH}"; // 本地文件系统路径 // const public_path = "https://example.com/assets/"; // 远程服务路径 let config: Config = { publicPath: public_path, // wasm 与模型文件所在路径 }; let image_src: Buffer | ArrayBuffer | Uint8Array | Blob | URL | string = ...; removeBackground(image_src, config).then((blob: Blob) => { // 结果为 PNG 编码的 Blob const url = URL.createObjectURL(blob); });

6.1 资源分块与 resources.json 元数据(源码级补充)

为什么需要把整个dist/目录拷贝过去?因为模型并不是以单个大文件方式加载的。从 packages/node/src/resource.ts 与 scripts/package-resources.mjs 可以看到:

  • 打包阶段,脚本会把模型文件按4 MB 默认块大小切分(DefaultChunkSize = 4 * 1024 * 1024),每个分块以其内容的 SHA-256 哈希作为文件名写入dist/,同时生成resources.json元数据(记录每个资源的chunks列表、每个块的哈希与offsets区间、总大小与 MIME 类型);
  • 运行时,loadAsBlob首先从publicPath下的resources.json读取元数据,再按chunks逐个分块拉取,校验每个分块大小后合并成完整的模型Blob,最后还要校验总大小是否与元数据一致,不一致会抛出错误(如Failed to fetch ${key} with size ${chunkSize} but got ${blob.size})。

这带来两个好处(对应 CHANGELOG 1.3.0 的说明):更利于缓存(每块 4 MB 可独立缓存)以及支持下载断点续传。因此,publicPath指向的目录必须同时包含分块文件与resources.json,否则会抛出“Resource metadata not found”或“Resource … not found”的明确错误,提示你检查config.publicPath配置是否正确。

七、调试输出

开启后会在控制台输出模型加载、ONNX 运行环境等信息:

let config: Config = { debug: true };

从源码看debug的具体作用(packages/node/src/schema.ts、packages/node/src/onnx.ts):

  • 配置校验后打印完整Config对象;
  • 若未显式设置progress,会自动注册一个默认的调试版进度回调(输出Downloading ${key}: ${current} of ${total});
  • 创建 ONNX 会话时开启ort.env.debug = true、ort.env.logLevel = 'verbose',并打印ort.env.wasm环境信息;
  • 加载模型前打印Loading model...(packages/node/src/inference.ts)。

八、CORS 与 fetchArgs

如果你通过 HTTP(S) 加载模型或图片资源时遇到 CORS 问题,可以通过fetchArgs向 fetch 传递附加参数:

let config: Config = { fetchArgs: { mode: 'no-cors' } };

README 说明:fetchArgs会作为 fetch 的第二个参数透传,其语义与 MDN Fetch API 文档 一致。值得注意:Node 端默认走file://本地加载,通常不会遇到 CORS 问题;当你切换到远程https://托管(自定义资源托管场景)或传远程图片 URL 时,才可能需要调整这里的请求头/模式。在 packages/node/src/resource.ts 中,loadFromURI对http:/https:协议直接使用fetch(uri),因此fetchArgs会在此处生效。

九、进阶 API:前景、背景、蒙版与任意图蒙版合成

当前版本(1.7.0)的公共导出在 packages/node/src/index.ts 中定义,共四个函数:removeBackground、removeForeground、segmentForeground、applySegmentationMask。

API语义实现要点
removeBackground抠出前景,背景透明推理得到的 alpha 蒙版直接写入 RGBA 的 alpha 通道(data[4*i+3] = alpha)后编码输出
removeForeground反向操作,保留背景、抹掉前景alpha 通道取反(255 - alpha)
segmentForeground只导出 alpha 蒙版output.format为image/x-alpha8时直接输出单通道蒙版;否则输出“红绿蓝 = 蒙版值、alpha=255”的灰度可视化图
applySegmentationMask将任意蒙版应用到任意图片蒙版与图片尺寸不一致时先用tensorResizeBilinear双线性插值缩放蒙版,再把蒙版写入图片 alpha 通道(1.4.0 新增,官方场景是“对同一蒙版批量套用到 srcsets”)

例如官方文档场景“先用segmentForeground提取蒙版,再批量应用到同源多尺寸图集”:

import { removeBackground, segmentForeground, applySegmentationMask } from "@imgly/background-removal-node"; const mask = await segmentForeground(image_src, config); // 提取 alpha 蒙版 const result = await applySegmentationMask(image_src, mask, config); // 应用到任意图片

仓库示例 packages/node-examples/src/example_001.cjs 中还给出了把结果 Blob 写入本地文件的完整流程(blob.arrayBuffer()→Buffer.from→fs.promises.writeFile),并展示了model: 'isnet'、format: 'image/webp'等实际配置组合。

十、底层原理:一次抠图的完整调用链

以默认配置调用removeBackground为例,完整链路如下(对应 packages/node/src/index.ts、packages/node/src/inference.ts、packages/node/src/onnx.ts):

  1. 配置校验:validateConfig(configuration)用 zod 的ConfigSchema解析并填充默认值(packages/node/src/schema.ts);
  2. 会话初始化(记忆化):init = memoize(initInference, config => JSON.stringify(config)),同一配置只初始化一次;initInference根据config.model以/models/${model}为键加载模型(packages/node/src/inference.ts);
  3. 资源加载:loadAsBlob读取resources.json→ 并行拉取各分块 → 合并校验 → 得到模型Blob(packages/node/src/resource.ts);
  4. 创建 ONNX 会话:ort.InferenceSession.create,会话选项为graphOptimizationLevel: 'all'与executionMode: 'parallel'(packages/node/src/onnx.ts);
  5. 图像预处理:输入图经tensorResizeBilinear缩放到1024×1024(推理固定分辨率),再经tensorHWCtoBCHW转成 BCHW 布局并归一化——注意源码中的归一化系数是mean=[128,128,128]、std=[256,256,256],即(pixel - 128) / 256(packages/node/src/utils.ts);
  6. 推理:以[['input', inputTensor]]为输入、['output']为输出执行session.run,得到 Float32 预测张量;
  7. 蒙版后处理:convertFloat32ToUint8把浮点 alpha 乘 255 转成 Uint8,再用双线性插值把蒙版从 1024×1024 放大回原始图片尺寸(1.3.0 起输出保持原图大小,蒙版上采样后应用,见 CHANGELOG);
  8. 像素合成与编码:把 alpha 写入 RGBA 第 4 通道,交由 packages/node/src/codecs.ts 的imageEncode用 sharp 按目标格式编码(image/png/image/jpeg/image/webp走sharp().toFormat(format, { quality: quality * 100 });image/x-rgba8/image/x-alpha8则直接以携带width=…;height=…参数的 MIME 类型包装原始像素字节),最终返回Blob。

依赖层面,packages/node/package.json 的核心依赖为onnxruntime-node(推理引擎)、sharp(图像编解码)、zod(配置校验)、ndarray(像素张量容器)与lodash(memoize),清晰反映了上述调用链各环节的承载者。

十一、适用场景

根据 README 的定位,该库适合以下典型场景:

  • 电商应用:实时为商品图移除背景,免去人工抠图成本;
  • 图像编辑应用:为照片编辑工具提供背景移除/抠图能力,增强用户体验;
  • Web 端图形设计工具:在浏览器/服务端简化创作流程中的背景处理环节;
  • 批量处理与自动化流水线:Node.js 环境意味着可以方便地接入脚本、CI、批量任务(仓库示例即演示了 CLI 式批量处理并落盘)。

无论你是专业开发者还是爱好者,都可以低成本地将该能力集成进自己的应用。

十二、许可证与进一步阅读

  • 许可证:该软件基于AGPL License免费使用;需要其他授权条款请直接联系 support@img.ly(参见 packages/node/LICENSE.md 与 CHANGELOG 1.4.0 “Changed license from GPL to AGPL”记录)。
  • 变更历史:完整的版本演进详见 packages/node/CHANGELOG.md。
  • 源码阅读入口:入口导出 packages/node/src/index.ts、配置校验 packages/node/src/schema.ts、推理管线 packages/node/src/inference.ts、ONNX 会话 packages/node/src/onnx.ts、分块资源加载 packages/node/src/resource.ts、编解码 packages/node/src/codecs.ts,以及可运行示例 packages/node-examples/src/example_001.cjs。
  • 计算机视觉
  • 图像处理
  • AI 应用

【免费下载链接】background-removal-js

Remove backgrounds from images directly in the browser environment with ease and no additional costs or privacy concerns. Explore an interactive demo.

项目地址:https://gitcode.com/gh_mirrors/ba/background-removal-js
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询