文檔目錄
於此處獲取完整文檔目錄: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:自输入构建,链式变换,择输出格式,而后await 乃终端之法。未待终端,则无物可运行,而工作乃于JavaScript线程之外施行。
输入
构造函数可纳路径、字节,或Blob —— 含Bun.file() 与Bun.s3()。Blob#image() 乃new Bun.Image(blob) 之简写:
new Bun.Image("./photo.jpg"); // file path
new Bun.Image(buffer); // Buffer / ArrayBuffer / TypedArray
new Bun.Image(Bun.file("photo.jpg")); // BunFile (read lazily, off-thread)
Bun.file("photo.jpg").image(); // same as above
Bun.s3("bucket/photo.jpg").image(); // S3File
格式自字节中察之,其扩展名与Content-Type 皆不顧。
路徑字串乃文件系統之途徑。 切莫直將受使用者控制之字串傳入構造函數——此乃隨意文件讀取之原語。讀入不可信輸入至一 Buffer(例如,透過 fetch/Bun.file 並以己之驗證),然後傳其字節。
當傳入一 TypedArray 時ArrayBuffer,勿变其形,俟终端待命之时——解码离线运行,借字节而行。SharedArrayBuffer与可变缓冲拒绝;当以buf.slice()传定规之视。
复一options之论,御解压炸弹之患,制EXIF之理:
new Bun.Image(input, {
// Reject if width*height > this. Checked after reading the header,
// before allocating the pixel buffer. Default matches Sharp (~268 MP).
maxPixels: 4096 * 4096,
// Apply JPEG EXIF Orientation before any other op. Default: 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); // width 800, keep aspect ratio
img.resize(800, 600); // exactly 800×600 (stretch)
img.resize(800, 600, { fit: "inside" }); // fit within 800×600
img.resize(800, 600, { withoutEnlargement: true }); // never upscale
img.resize(800, 600, { filter: "mitchell" });
fit | 行止 |
|---|---|
"fill"(默认) | 舒展至恰如其分width × height |
"inside" | 保持长宽比;结果适配其中匣也 |
filter择取重采样之核。其默认"lanczos3"此乃摄影之良选。
| 筛之 | 用之 |
|---|---|
"lanczos3" (默认) | 通用,最利摄影 |
"lanczos2" | 稍柔和,铃响之迹少 |
"mitchell" | 渐变圆滑;古雅之双三次折衷 |
"cubic" | 卡特穆尔—较米切尔锐利,可铃响 |
"mks2013" / "mks2021" | “魔法核锐利”;由Facebook/Instagram用之 |
"bilinear" / "linear" | 速,柔和 |
"box" | 区域平均;宜于大整数下采样 |
"nearest" | 像素画 / 硬边 |
源为JPEG而目标至多为源大小之半时,解码直接跳至最近M/8 IDCT缩放,故自24MP照片生成为缩略图,永无全分辨率缓冲之实
旋转 · 翻转
img.rotate(90); // 90° clockwise (multiples of 90 only)
img.flip(); // mirror vertically (about the x-axis)
img.flop(); // mirror horizontally (about the y-axis)
调制
img.modulate({
brightness: 1.2, // 1 = unchanged
saturation: 0, // 0 = greyscale, 1 = unchanged, >1 = boost
});
输出格式
调格式法,立编码之向;无之,则复用源格式。
img.jpeg({ quality: 85 }); // 1–100, default 80
img.png({ compressionLevel: 6 }); // zlib level 0–9
img.png({ palette: true, colors: 64, dither: true }); // indexed PNG
img.webp({ quality: 80 });
img.webp({ lossless: true });
img.heic({ quality: 80 }); // macOS / Windows only
img.avif({ quality: 60 }); // macOS / Windows only
palette: true量化至≤256色之调板,发索引式(色类三)之PNG,或附弗洛伊德-斯坦伯格dither。此较真色,于截图及界面资材,常小三至五倍。
终端
管流未作,必待此中之一。
await img.bytes(); // Uint8Array
await img.buffer(); // Buffer
await img.blob(); // Blob with .type set to the output MIME
await img.toBase64(); // string
await img.dataurl(); // "data:image/png;base64,…"
await img.write("out.webp"); // number (bytes written)
await img.write(Bun.s3("bucket/out.webp"));
.write() 与 Bun.write 同途,受径名、Bun.file()、Bun.s3() 或 fd。若未缀格式法,而径名为文,则缀延自择其一(.jpg/.png/.webp/.heic/.avif)。
之占位符。
欲于HTML中预置低质占位符,俟真图载入,.placeholder()则返一ThumbHash所成之≤32像素模糊图像,作data:之URL——约400–700字节,无需客户端解码器:
const lqip = await Bun.file("hero.jpg").image().placeholder();
// <img src={lqip} … /> — then swap to the real URL on load.
欲于图像本身施由粗至精之渲染,则当编渐进式JPEG。
img.jpeg({ progressive: true });
初端解,img.width且img.height映照之输出尺寸(他们的是)-1此前也。
Bun.serve融通
一Bun.Image管道乃合法也Response形与势Content-Type 自動化之。若於伺服器處理中使編碼不干擾 JS 線程,須先待終端:
Bun.serve({
routes: {
"/avatar/:id": async req => {
// Validate before touching the filesystem (see the Input note above).
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)) 亦有效,然目前於體初階同步運行編碼。
Clipboard
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若无图像,恒然null于 Linux — 呼wl-paste/xclip尔身自将字节以授构造函数。
若欲粘贴剪贴板之图像,按⌘V,此乃提示也,请询之。clipboardChangeCount()(读一整数)并调用hasClipboardImage()唯动则显;macOS无剪贴板变更之告,故此乃载于文者。
平台后端
| Linux | macOS | Windows | |
|---|---|---|---|
| JPEG / PNG / WebP | libjpeg-turbo · spng · libwebp | 同 | 同 |
| BMP / GIF (解码) | 内置 | ImageIO | WIC |
| TIFF (解码) | ❌ | 图像输出 | WIC |
| 缩放 / 旋转 / 翻转 | 高速 SIMD | 加速 vImage | 高速 SIMD |
| HEIC / AVIF | ❌ ERR_IMAGE_FORMAT_UNSUPPORTED | 图像输出 ² | WIC ¹ |
| 剪贴板 | ❌ 返回 null | NSPasteboard | Win32 |
¹ Windows需HEIF Image Extensions / AV1 Video Extension于Microsoft Store。
² AVIF encode需OS AV1编码器—仅Apple Silicon M3+可用。Intel Mac及M1/M2则拒之,以ERR_IMAGE_FORMAT_UNSUPPORTED;AVIF decode 处处可用,如 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"; // default is "system" on macOS/Windows












