Bun.Image

Hacker News Top 工具

摘要

Bun.Image 是一个零依赖的可链式图像处理管道,用于解码、调整大小、旋转和重新编码 JPEG、PNG、WebP、HEIC 和 AVIF 格式,在后台线程运行,灵感来自 Sharp。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/05/24 00:35

# Image - Bun 来源:https://bun.com/docs/runtime/image > ## 文档索引 获取完整文档索引:https://bun.com/docs/llms.txt 使用此文件在进一步探索前发现所有可用页面。 `Bun.Image` 是一个可链式调用的图像处理流水线,用于解码、调整大小、旋转和重新编码 JPEG、PNG、WebP、HEIC 和 AVIF 格式 —— 基于 libjpeg-turbo、spng、libwebp 和 SIMD 几何内核,零 npm 依赖,无需原生插件构建步骤。 `` await Bun.file("photo.jpg").image().resize(400, 400, { fit: "inside" }).webp({ quality: 80 }).write("thumb.webp"); `` 该 API 的设计借鉴了 Sharp(https://sharp.pixelplumbing.com/):从输入构建,链式调用变换,选择输出格式,然后 `await` 一个终端方法。在终端方法被 await 之前不会执行任何操作,并且处理工作在 JavaScript 线程之外执行。 ## 输入 构造函数接受路径、字节或 `Blob` —— 包括 `Bun.file()` 和 `Bun.s3()`。`Blob#image()` 是 `new Bun.Image(blob)` 的简写: `` new Bun.Image("./photo.jpg"); // 文件路径 new Bun.Image(buffer); // Buffer / ArrayBuffer / TypedArray new Bun.Image(Bun.file("photo.jpg")); // BunFile(延迟读取,离线程) Bun.file("photo.jpg").image(); // 同上 Bun.s3("bucket/photo.jpg").image(); // S3File `` 格式从字节中嗅探 —— 扩展名和 `Content-Type` 被忽略。 **路径字符串是文件系统路径。** 不要直接将用户控制的字符串传递给构造函数 —— 这会构成任意文件读取原语。将不受信任的输入读入 `Buffer`(例如通过 `fetch`/`Bun.file` 并结合你自己的验证),然后传递字节。 当传递 `TypedArray`/`ArrayBuffer` 时,不要在终端操作挂起时对其进行修改 —— 解码离线程运行并借用这些字节。`SharedArrayBuffer` 和可调整大小的缓冲区被拒绝;请使用 `buf.slice()` 传递一个固定视图。 第二个 `options` 参数用于防止解压缩炸弹并控制 EXIF 处理: `` new Bun.Image(input, { // 如果 width*height 超过此值则拒绝。在读取头部后、 // 分配像素缓冲区之前检查。默认值与 Sharp 大致相同(约 268 百万像素)。 maxPixels: 4096 * 4096, // 在其他操作之前应用 JPEG EXIF 方向。默认值:true。 autoOrient: true, }); `` 在不解码像素数据的情况下读取 `width`、`height` 和 `format`: `` const { width, height, format } = await new Bun.Image(input).metadata(); // => { width: 1920, height: 1080, format: "jpeg" } `` ## 调整大小 `` img.resize(800); // 宽度 800,保持宽高比 img.resize(800, 600); // 精确 800×600(拉伸) img.resize(800, 600, { fit: "inside" }); // 适应 800×600 之内 img.resize(800, 600, { withoutEnlargement: true }); // 从不放大 img.resize(800, 600, { filter: "mitchell" }); `` `fit`行为`"fill"`(默认)拉伸到精确的 `width × height``"inside"`保持宽高比;结果适应*在*框内 `filter` 选择重采样内核。默认的 `"lanczos3"` 是照片的正确选择。 Filter使用场景`"lanczos3"`*(默认)*通用,最适合照片`"lanczos2"`稍柔,减少振铃伪影`"mitchell"`平滑渐变;经典双三次折中`"cubic"`Catmull-Rom —— 比 Mitchell 更锐利,可能产生振铃`"mks2013"`/`"mks2021"`”Magic Kernel Sharp”;被 Facebook/Instagram 使用`"bilinear"`/`"linear"`快速、柔化`"box"`面积平均;适合大的整数缩小`"nearest"`像素艺术 / 硬边缘 当源文件是 JPEG 且目标尺寸最多为源文件尺寸的一半时,解码将直接跳到最近的 M/8 IDCT 缩放,因此从 2400 万像素的照片生成缩略图永远不会实例化全分辨率缓冲区。 ## 旋转 · 翻转 `` img.rotate(90); // 顺时针 90°(仅限 90 的倍数) img.flip(); // 垂直镜像(关于 x 轴) img.flop(); // 水平镜像(关于 y 轴) `` ## 调制 `` img.modulate({ brightness: 1.2, // 1 表示不变 saturation: 0, // 0 表示灰度,1 表示不变,>1 表示增强 }); `` ## 输出格式 调用格式方法会设置编码目标;如果没有调用,则复用源格式。 `` img.jpeg({ quality: 85 }); // 1–100,默认 80 img.png({ compressionLevel: 6 }); // zlib 级别 0–9 img.png({ palette: true, colors: 64, dither: true }); // 索引 PNG img.webp({ quality: 80 }); img.webp({ lossless: true }); img.heic({ quality: 80 }); // 仅 macOS / Windows img.avif({ quality: 60 }); // 仅 macOS / Windows `` `palette: true` 将量化到 ≤256 色调色板并输出索引(颜色类型 3)PNG,可选地使用 Floyd–Steinberg `dither`。对于截图和 UI 资源,这通常比真彩色小 3–5 倍。 ## 终端方法 在 await 以下之一之前,流水线不会执行任何工作: `` await img.bytes(); // Uint8Array await img.buffer(); // Buffer await img.blob(); // Blob,.type 设置为输出 MIME 类型 await img.toBase64(); // 字符串 await img.dataurl(); // "data:image/png;base64,..." await img.write("out.webp"); // 数字(写入的字节数) await img.write(Bun.s3("bucket/out.webp")); `` `.write()` 接受与 `Bun.write` 相同的目的地 —— 路径字符串、`Bun.file()`、`Bun.s3()` 或文件描述符。如果你没有链式调用格式方法,并且目的地是路径字符串,则扩展名会选择一个格式(`.jpg`/`.png`/`.webp`/`.heic`/`.avif`)。 ## 占位符 为了在真实图像加载之前内联到 HTML 中的低质量占位符,`.placeholder()` 返回一个基于 ThumbHash(https://evanw.github.io/thumbhash/)渲染的 ≤32px 模糊占位符,作为 `data:` URL —— 约 400–700 字节,无需客户端解码器: `` const lqip = await Bun.file("hero.jpg").image().placeholder(); // — 然后在加载时替换为真实 URL。 `` 对于图像*本身*的粗到细渲染,请编码为渐进式 JPEG: `` img.jpeg({ progressive: true }); `` 在第一个终端方法解析后,`img.width` 和 `img.height` 反映*输出*尺寸(之前为 `-1`)。 ## `Bun.serve` 集成 `Bun.Image` 流水线可以作为合法的 `Response` 主体,并自动设置 `Content-Type`。为了在服务器处理程序中将编码保持在 JS 线程之外,先 await 一个终端方法: `` Bun.serve({ routes: { "/avatar/:id": async req => { // 在接触文件系统之前进行验证(参见上面的输入说明)。 if (!/^[a-z0-9]+$/.test(req.params.id)) return new Response(null, { status: 400 }); const out = await Bun.file(`avatars/${req.params.id}.png`).image().resize(128, 128).webp().blob(); return new Response(out); }, }, }); `` 直接传递流水线(`new Response(img)`)也可以,但目前会在主体初始化期间同步执行编码。 ## 剪贴板 `` const img = Bun.Image.fromClipboard(); if (img) { const png = await img.resize(800, 800, { fit: "inside" }).png().bytes(); } `` `fromClipboard()` 在 macOS 和 Windows 上从系统剪贴板读取 PNG、TIFF、HEIC、JPEG、WebP、GIF 或 BMP;然后常规解码流水线接管。如果没有图像则返回 `null`,在 Linux 上始终返回 `null` —— 请自行调用 `wl-paste`/`xclip` 并将字节传递给构造函数。 对于被动的“图像在剪贴板中,按 ⌘V”提示,请轮询 `clipboardChangeCount()`(单个整数读取),并仅在发生变化时调用 `hasClipboardImage()`;macOS 没有剪贴板更改通知,因此这是文档化的模式。 ## 平台后端 LinuxmacOSWindowsJPEG / PNG / WebPlibjpeg-turbo · spng · libwebp相同相同BMP / GIF(解码)内置ImageIOWICTIFF(解码)❌ImageIOWIC调整大小 / 旋转 / 翻转Highway SIMDAccelerate vImageHighway SIMDHEIC / AVIF❌`ERR_IMAGE_FORMAT_UNSUPPORTED`ImageIO 2WIC 1剪贴板❌ 返回 `null`NSPasteboardWin32 1 Windows 需要从 Microsoft Store 安装 **HEIF 图像扩展** / **AV1 视频扩展**。 2 AVIF *编码* 需要操作系统 AV1 编码器 —— 仅限 Apple Silicon M3+。Intel Mac 和 M1/M2 拒绝并返回 `ERR_IMAGE_FORMAT_UNSUPPORTED`;AVIF *解码* 在 ImageIO 支持的任意位置(macOS 13+)均可工作。 当当前机器上无法使用系统后端格式时,终端方法拒绝并返回 `error.code === "ERR_IMAGE_FORMAT_UNSUPPORTED"` —— 可以以此分支回退到可移植格式: `` const out = await img .avif({ quality: 50 }) .bytes() .catch(e => { if (e.code === "ERR_IMAGE_FORMAT_UNSUPPORTED") return img.webp({ quality: 80 }).bytes(); throw e; }); `` 由系统后端处理的格式(TIFF、HEIC、AVIF、剪贴板)继承**操作系统**的补丁级别 —— 请保持 macOS / Windows 更新。JPEG、PNG 和 WebP 在每个平台上都通过相同的静态链接编解码器处理,因此编码输出在 Linux、macOS 和 Windows 上是字节一致的。 为了在几何变换上也强制使用可移植的 Highway 路径 —— 例如用于黄金图像测试 —— 设置进程全局后端: `` Bun.Image.backend = "bun"; // 在 macOS/Windows 上默认是 "system" ``

相似文章

1-Bit Bonsai Image 4B 本地设备图像生成

Hacker News Top

PrismML 发布 Bonsai Image 4B,这是一系列紧凑型图像生成模型,使用 1-bit 和三进制权重,能够在笔记本电脑和 iPhone 等本地设备上实现高质量扩散推理,同时显著减少内存占用。

prism-ml/bonsai-image-ternary-4B-gemlite-2bit

Hugging Face Models Trending

Prism ML发布Bonsai Image,一个1.21 GB的文本到图像扩散变换器,使用三元权重(1.58-bit)用于NVIDIA GPU,在RTX 3080上4.5秒生成1024²图像,体积远小于FP16。

prunaai/p-image

Replicate Explore

P-Image 是 Pruna 的文本到图像生成模型,可在不到一秒内生成最先进的图像,兼具速度、经济性和高质量。