sharp.js安装不上, Bun.Image说: 我不用安装

Bun设计的API一直都是简单, 优雅

bash 复制代码
import { Image } from 'bun';  // 全局可用,无需导入

// 最简示例
await Bun.file('photo.jpg')
  .image()
  .resize(800, 600)
  .webp({ quality: 80 })
  .write('thumb.webp');

为什么换掉 sharp?

sharp 是 Node.js 最流行的图片库,但安装痛苦,需要编译原生模块、CI 经常失败。

bash 复制代码
# sharp 的日常
npm install sharp  # 可能失败,Alpine 需要 apk add vips-dev
# CI 缓存频繁失效

Bun.Image 是什么?

Bun v1.3.14+ 内置的链式图像处理 API,用 Zig 实现,编译进 Bun 二进制文件。输入灵活,输出多样,支持 JPEG/PNG/WebP 等主流格式,性能接近或超过 sharp。

bash 复制代码
import { Image } from 'bun';  // 全局可用,无需导入

// 最简示例
await Bun.file('photo.jpg')
  .image()
  .resize(800, 600)
  .webp({ quality: 80 })
  .write('thumb.webp');

输入源:文件、Buffer、Blob 都行

你可以直接传入文件路径、ArrayBuffer、TypedArray、Blob、BunFile 甚至 data: URL。所有输入都是零拷贝设计,避免不必要的内存复制。

bash 复制代码
// 文件路径
Bun.file('input.jpg').image()

// Buffer / ArrayBuffer(零拷贝)
const buffer = await fetch(url).arrayBuffer();
new Image(buffer).resize(200).jpeg()

// Blob / BunFile
const blob = new Blob([data], { type: 'image/png' });
new Image(blob).png().write('out.png')

输出方式:Buffer/Blob/Response 随意选

处理完的图片可以写入文件、转为 Buffer、生成 Base64,甚至可以当作 Response body 直接返回(自动设置 Content-Type)。

bash 复制代码
const img = Bun.file('test.jpg').image().resize(300);

await img.write('out.jpg');       // 写文件
const buf = await img.buffer();   // ArrayBuffer
const bytes = await img.bytes();  // Uint8Array
const b64 = await img.toBase64(); // Base64 字符串

// 直接返回 HTTP 响应
return new Response(await img.jpeg());

链式变换:缩放、旋转、调色

Bun.Image 提供了和 sharp 类似的链式 API:resize、rotate(90的倍数)、flip/flop、modulate(亮度/饱和度)。每个操作都返回新实例,不修改原图。

bash 复制代码
Bun.file('in.png')
  .image()
  .resize(800, null, { fit: 'cover', withoutEnlargement: true })
  .flip()                       // 垂直翻转
  .rotate(90)                   // 仅支持 90/180/270
  .modulate({ brightness: 1.2, saturation: 0.8 })
  .webp({ quality: 80 })
  .write('out.webp');

格式支持矩阵

解码:所有平台都支持 JPEG/PNG/WebP/GIF(静态)/BMP;macOS/Windows 额外支持 HEIC/AVIF/TIFF。编码:JPEG/PNG/WebP 全平台;HEIC/AVIF 仅 macOS/Windows;BMP/TIFF/GIF 不支持编码。

| 格式 | 解码 | 编码 | 备注 | | :-- | :-- | :-- | :-- | | JPEG | ✅ | ✅ | | | PNG | ✅ | ✅ | | | WebP | ✅ | ✅ | | | GIF | ✅ | ❌ | 仅静态帧 | | BMP | ✅ | ❌ | | | HEIC | ✅* | ✅* | *macOS/Windows | | AVIF | ✅* | ✅* | *macOS/Windows |

性能亮点:metadata 快 70 倍

sharp 的 metadata() 需要完整解码图像才能拿到宽高,而 Bun.Image 只读取文件头部几百字节就直接返回。缩放操作两者持平,但 Bun.Image 内存占用更低(约-40%)。

bash 复制代码
// metadata 对比
// sharp: 读取整张 4K 图片(~10MB)
const meta = await sharp('4k.jpg').metadata(); // ~21ms

// Bun.Image: 只读头部
const meta = await Bun.file('4k.jpg').image().metadata(); // ~0.3ms

// 缩放性能(4K→1080p):Bun.Image 快约 10-20%
// 并发 50 任务:sharp 160ms,Bun.Image 约 130ms

从 sharp 迁移:四步替换

第一步替换构造函数;第二步把 .toFormat('webp') 改为 .webp();第三步注意 metadata 要先 .image();第四步调整输出方法(.toBuffer() → .buffer())。

bash 复制代码
// Before (sharp)
import sharp from 'sharp';
const out = await sharp('in.jpg')
  .resize(800)
  .toFormat('webp')
  .toBuffer();

// After (Bun.Image)
const out = await Bun.file('in.jpg')
  .image()
  .resize(800)
  .webp()      // 格式方法作为 pipeline 终点
  .buffer();

// metadata 迁移
// sharp: await sharp(buf).metadata()
// Bun.Image: await Bun.file(buf).image().metadata()

局限性:不是所有 sharp 功能都有

Bun.Image 目前不支持文本叠加、SVG 渲染、任意角度旋转(仅 90 倍数)、复杂裁剪路径、GIF 动画、多页 TIFF,以及 BMP/TIFF/GIF 的编码。Linux 上也不支持 HEIC/AVIF 解码。

bash 复制代码
// ❌ 这些暂不支持
// - 文本水印 / SVG 绘图
// - .rotate(45) 任意角度
// - .composite([...])
// - GIF 动画编码
// - Linux 上读取 HEIC

// ✅ 90% 场景够用:缩略图、格式转换、质量压缩、元数据

结论:大多数项目可以直接换

如果你只需要缩略图、格式互转、质量压缩、快速获取宽高,Bun.Image 零依赖、更快、更省内存。只有遇到文本水印、任意旋转、专业摄影流程时才需要保留 sharp。

bash 复制代码
// 推荐方案:Bun.Image 主力,sharp 兜底
const useSharp = needTextOverlay || needFreeRotate;
if (!useSharp) {
  await Bun.file('input').image().resize(200).webp().write('out.webp');
} else {
  await sharp('input').resize(200).webp().toFile('out.webp');
}
相关推荐
无风听海1 小时前
ASP.NET Core 中的重定向(Redirect)深度解析
后端·asp.net
陈_杨1 小时前
鸿蒙APP开发-带你走进黑胶阁的唱片收藏怎么管理
前端·javascript
一天 24h1 小时前
Pinia 新手完全指南:从入门到精通的实战教程
前端·javascript·vue.js·pycharm·前端框架
掘金者阿豪1 小时前
Node.js 连金仓数据库(下篇):连接池、事务和那些坑
后端
向日的葵0061 小时前
快速了解vue中的路由如何实现(路由一)
前端·vue.js·vue·路由
珎珎啊1 小时前
React 和 Vue 3的区别
前端·vue.js·react.js
shadow_glory1 小时前
vue3自定义指令directives
前端·javascript·vue.js
Front思1 小时前
如何学习Shopify前端开发?
前端·学习
码云骑士1 小时前
语音合成演示 - Web Speech API
前端