慣性聚合 高效追讀感興趣之博客、新聞、科技資訊
閱原文 以慣性聚合開啟

推薦訂閱源

博客园 - 司徒正美
V
V2EX
T
Tailwind CSS Blog
有赞技术团队
有赞技术团队
aimingoo的专栏
aimingoo的专栏
Apple Machine Learning Research
Apple Machine Learning Research
IT之家
IT之家
Blog — PlanetScale
Blog — PlanetScale
A
About on SuperTechFans
月光博客
月光博客
T
The Blog of Author Tim Ferriss
宝玉的分享
宝玉的分享
Martin Fowler
Martin Fowler
博客园 - 聂微东
The GitHub Blog
The GitHub Blog
V
Visual Studio Blog
WordPress大学
WordPress大学
酷 壳 – CoolShell
酷 壳 – CoolShell
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI

Hacker News: Front Page

Trump administration reclassifies cannabis as less dangerous Release raylib v6.0 · raysan5/raylib GitHub - russellromney/honker: SQLite extension + bindings for Postgres NOTIFY/LISTEN semantics with durable queues, streams, pub/sub, and scheduler Writing a C Compiler, in Zig crawshaw - 2026-04-22 MacBook Neo and How the iPad Should Be Convergent Evolution: How Different Language Models Learn Similar Number Representations It's time to reclaim the word "Palantir" for J.R.R. Tolkien Arch Linux now has a bit-for-bit reproducible Docker image Fundamental Theorem of Calculus | David Álvarez Rosa | Personal Website Bring Your Agent to Teams Ars Technica newsroom AI policy France confirms data breach at government agency that manages citizens’ IDs New study compares growing corn for energy to solar production. It's no contest NAEP Long-Term Trend Assessment Results: Reading and Mathematics We found a stable Firefox identifier linking all your private Tor identities GitHub - besimple-oss/broccoli: Broccoli turns Linear tickets into shipped PRs — powered by Claude and Codex, running on your own Google Cloud. Youth Suicides Declined After Creation of National Hotline Top MAGA influencer revealed to be AI — created by a guy in India who made a mint off lonely men online Ping-pong robot beats top-level human players Announcing DuckDB 1.5.2 The handmade beauty of Machine Age data visualizations Treetops glowing during storms captured on film for first time Columnar Storage is Normalization TPU 8t and TPU 8i technical deep dive Our eighth generation TPUs: two chips for the agentic era Introducing Google Cloud Fraud Defense, the next evolution of reCAPTCHA Kernel code removals driven by LLM-created security reports tante.cc Nobody Got Fired for Uber's $8 Million Ledger Mistake? Introducing workspace agents in ChatGPT Sure, xor’ing a register with itself is the idiom for zeroing it out, but why not sub? What Async Promised and What it Delivered — Causality GitHub - justrach/kuri: Browser automation and web crawling for AI agents. Zig-native, token-efficient CDP snapshots, HAR recording, and a standalone fetcher. Drunk Post: Things I’ve Learned as a Senior Engineer Claude Code to be removed from Anthropic's Pro plan? Another Day Has Come ‘Something sinister could be happening’: FBI looks into dead or missing nuclear and space defense scientists tied to NASA, Blue Origin, and SpaceX GitHub - calcom/cal.diy: Scheduling infrastructure for absolutely everyone. Meta to start capturing employee mouse movements, keystrokes for AI training The Vercel Breach: OAuth Supply Chain Attack Exposes the Hidden Risk in Platform Environment Variables Member of Technical Staff, Product Engineering (full-time) at Trellis AI | Y Combinator CATL's new LFP battery can charge from 10 to 98% in less than 7 minutes Jobs at Bloom | Y Combinator The printing press for biological data (Sterling Hooten) Brussels launched an age checking app. Hackers took 2 minutes to break it Inside GitHub's Fake Star Economy The Illuminated Man by Christopher Priest and Nina Allan review – an unconventional portrait of JG Ballard IEA: Solar overtakes all energy sources in a major global first Stripe’s payments APIs: The first 10 years
图像 - 炮弹
chakintosh · 2026-05-24 · via Hacker News: Front Page

文檔目錄

於此處獲取完整文檔目錄: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 並以己之驗證),然後傳其字節。 當傳入一 TypedArrayArrayBuffer,勿变其形,俟终端待命之时——解码离线运行,借字节而行。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,
});

widthheight,及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.widthimg.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无剪贴板变更之告,故此乃载于文者。

平台后端

LinuxmacOSWindows
JPEG / PNG / WebPlibjpeg-turbo · spng · libwebp
BMP / GIF (解码)内置ImageIOWIC
TIFF (解码)图像输出WIC
缩放 / 旋转 / 翻转高速 SIMD加速 vImage高速 SIMD
HEIC / AVIFERR_IMAGE_FORMAT_UNSUPPORTED图像输出 ²WIC ¹
剪贴板❌ 返回 nullNSPasteboardWin32

¹ 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