Bun.Image 是一个可链式调用的图像管道,用于解码、调整大小、旋转以及重新编码 JPEG、PNG、WebP、HEIC 和 AVIF——基于 libjpeg-turbo、spng、libwebp 和 SIMD 几何内核构建,零 npm 依赖,也无需原生插件构建步骤。
await。在终结方法被 await 之前,不会执行任何操作,且工作会在 JavaScript 线程之外执行。
输入
构造函数接受路径、字节或Blob——包括 Bun.file() 和 Bun.s3.file()。Blob#image() 是 new Bun.Image(blob) 的简写:
Content-Type。
**路径字符串是文件系统路径。**不要将用户控制的字符串直接传给构造函数——这会产生任意文件读取原语。请先使用 fetch 或 Bun.file 将不受信任的输入读入 Buffer,并进行你自己的验证,然后再传入这些字节。
当传入 TypedArray/ArrayBuffer 时,在终结方法尚未完成时不要修改它——解码会在线程外运行并借用这些字节。SharedArrayBuffer 和可调整大小的缓冲区会被拒绝;请使用 buf.slice() 传入固定视图。
第二个 options 参数用于防护解压炸弹并控制 EXIF 处理:
元数据
无需解码像素数据即可读取width、height 和 format:
调整大小
filter 用于选择重采样内核。默认的 "lanczos3" 是照片的最佳选择。
当源图像是 JPEG 且目标尺寸最多只有源尺寸的一半时,解码会直接跳到最接近的 M/8 IDCT 缩放,因此即使从一张 24 MP 照片生成缩略图,也不会生成完整分辨率缓冲区。
旋转 · 翻转
调节
输出格式
调用格式方法会设置编码目标;如果不调用,则复用源格式。palette: true 会量化为一个 ≤256 色调色板,并输出索引型(color-type 3)PNG,可选使用 Floyd–Steinberg dither。对于截图和 UI 资源,这通常比真彩色小 3–5 倍。
终结方法
在以下方法中的任意一个被await 之前,管道不会执行任何工作:
.write() 接受与 Bun.write 相同的目标类型——路径字符串、Bun.file()、Bun.s3.file() 或文件描述符。如果你没有链式调用格式方法,并且目标是路径字符串,则扩展名会决定格式(.jpg/.png/.webp/.heic/.avif)。
占位符
如果你想在真实图像加载前于 HTML 中内联一个低质量占位图,.placeholder() 会返回一个由 ThumbHash 渲染的、≤32px 的模糊 data: URL——约 400–700 字节,无需客户端解码器:
img.width 和 img.height 反映的是 输出 尺寸(在此之前它们为 -1)。
Bun.serve 集成
Bun.Image 管道是一个有效的 Response body,并会自动设置 Content-Type。为了在服务端处理程序中让编码保持在 JS 线程之外,请先 await 一个终结方法:
new Response(img))同样有效,但会在正文初始化期间同步执行编码。
剪贴板
fromClipboard() 会从 macOS 和 Windows 的系统剪贴板读取 PNG、TIFF、HEIC、JPEG、WebP、GIF 或 BMP;之后再交给常规解码管道处理。如果没有图像则返回 null,而在 Linux 上始终返回 null——请自行调用 wl-paste/xclip 并将字节传给构造函数。
如果你想要一个被动的“剪贴板里有图像,按 ⌘V”提示,可以轮询 clipboardChangeCount()(单个整数读取),并且只在它变化时调用 hasClipboardImage();macOS 没有剪贴板变化通知,所以这是文档化的模式。
平台后端
¹ Windows 需要来自 Microsoft Store 的 HEIF Image Extensions / AV1 Video Extension。
² AVIF 编码 需要系统级 AV1 编码器——仅 Apple Silicon M3+ 可用。Intel Mac 和 M1/M2 会以
ERR_IMAGE_FORMAT_UNSUPPORTED 拒绝;AVIF 解码 在所有 ImageIO 支持的地方都可用(macOS 13+)。
当当前机器上没有可用的系统后端格式时,终结方法会以 error.code === "ERR_IMAGE_FORMAT_UNSUPPORTED" 拒绝——可据此分支回退到可移植格式: