@ cf-wasm/ 图片
为Cloudflare工人,Next.js和Node.js的高性能 Rust图像处理库(Photon).
电源 @silvia-odwyer/图片
由犯罪建造 1390383
与上游同步于 2026-07-14 (IST)。 。 。 .
安装
npm install @cf-wasm/photon # npm
yarn add @cf-wasm/photon # yarn
pnpm add @cf-wasm/photon # pnpm
使用量
因为 package.json 包括: node, (中文(简体) ), workerd,以及 edge-light,通常可以直接从 @cf-wasm/photon 让运行时间选择正确的入站点 :
import { PhotonImage } from "@cf-wasm/photon";
如果您想要明确, 请从子模块导入 :
-
Cloudflare Workers / Pages (Wrangler): 云花工/页面(英语:
import { PhotonImage } from "@cf-wasm/photon/workerd"; -
Next.js Edge 运行时间 :
import { PhotonImage } from "@cf-wasm/photon/edge-light"; -
节点.js(内含):
import { PhotonImage } from "@cf-wasm/photon/node"; -
浏览器, Web Worker等(实验)
import { PhotonImage } from "@cf-wasm/photon/others";
[尖叫声] 云花板工人有严格的记忆盖(典型的)
128MB) (中文(简体) ). 为了避免超过这些限制,在处理前验证输入图像大小或拒绝超大小的图像.
实例
以下是图像被调整大小并转换为webp格式的一些例子:
云花岗工人
使用Cloudflare Workers的,可以使用如下: 1
// src/index.ts
import { PhotonImage, SamplingFilter, resize } from "@cf-wasm/photon/workerd";
export default {
async fetch() {
// url of image to fetch
const imageUrl = "https://avatars.githubusercontent.com/u/314135";
// fetch image and get the bytes
const inputBytes = await fetch(imageUrl)
.then((res) => res.arrayBuffer())
.then((buffer) => new Uint8Array(buffer));
// create a PhotonImage instance
const inputImage = PhotonImage.new_from_byteslice(inputBytes);
// resize image using photon
const outputImage = resize(
inputImage,
inputImage.get_width() * 0.5,
inputImage.get_height() * 0.5,
SamplingFilter.Nearest,
);
// get webp bytes
const outputBytes = outputImage.get_bytes_webp();
// for other formats
// png : outputImage.get_bytes();
// jpeg : outputImage.get_bytes_jpeg(quality);
// call free() method to free memory
inputImage.free();
outputImage.free();
return new Response(outputBytes, {
headers: {
"Content-Type": "image/webp",
},
});
},
} satisfies ExportedHandler;
Next.js (App路由器) (英语)
如果您正在使用 Next.js (App 路由器) 的边缘运行时间,您可以使用如下:
// (src/)app/api/image/route.ts
import { type NextRequest } from "next/server";
import {
PhotonImage,
SamplingFilter,
resize,
} from "@cf-wasm/photon/edge-light";
export const runtime = "edge";
export async function GET(request: NextRequest) {
// url of image to fetch
const imageUrl = "https://avatars.githubusercontent.com/u/314135";
// fetch image and get the bytes
const inputBytes = await fetch(imageUrl)
.then((res) => res.arrayBuffer())
.then((buffer) => new Uint8Array(buffer));
// create a PhotonImage instance
const inputImage = PhotonImage.new_from_byteslice(inputBytes);
// resize image using photon
const outputImage = resize(
inputImage,
inputImage.get_width() * 0.5,
inputImage.get_height() * 0.5,
SamplingFilter.Nearest,
);
// get webp bytes
const outputBytes = outputImage.get_bytes_webp();
// for other formats
// png : outputImage.get_bytes();
// jpeg : outputImage.get_bytes_jpeg(quality);
// call free() method to free memory
inputImage.free();
outputImage.free();
return new Response(outputBytes, {
headers: {
"Content-Type": "image/webp",
},
});
}
Next.js (页路由器)
如果您正在使用 Next.js (Pages 路由器) 的边缘运行时间,您可以使用如下:
// (src/)pages/api/image.ts
import { type NextRequest } from "next/server";
import {
PhotonImage,
SamplingFilter,
resize,
} from "@cf-wasm/photon/edge-light";
export const config = {
runtime: "edge",
// see https://nextjs.org/docs/messages/edge-dynamic-code-evaluation
unstable_allowDynamic: ["**/node_modules/@cf-wasm/**/*.js"],
};
export default async function handler(req: NextRequest) {
// url of image to fetch
const imageUrl = "https://avatars.githubusercontent.com/u/314135";
// fetch image and get the bytes
const inputBytes = await fetch(imageUrl)
.then((res) => res.arrayBuffer())
.then((buffer) => new Uint8Array(buffer));
// create a PhotonImage instance
const inputImage = PhotonImage.new_from_byteslice(inputBytes);
// resize image using photon
const outputImage = resize(
inputImage,
inputImage.get_width() * 0.5,
inputImage.get_height() * 0.5,
SamplingFilter.Nearest,
);
// get webp bytes
const outputBytes = outputImage.get_bytes_webp();
// for other formats
// png : outputImage.get_bytes();
// jpeg : outputImage.get_bytes_jpeg(quality);
// call free() method to free memory
inputImage.free();
outputImage.free();
return new Response(outputBytes, {
headers: {
"Content-Type": "image/webp",
},
});
}
网络工作者
你用得着 others 并使用 initPhoton 函数使其在其他运行时间(即:. Browser, (中文(简体) ), Web Worker(见e/cn.4/sub.2/2002/l.48等).
[尖叫声] 这个
others子模块尚属实验. 中断修改可以不遵循语义版本而引入.
@ deox/ worker- rpc 在使用网络工作人员时,可以使信息更加容易.
以下是Webpack捆绑器使用Webpack捆绑器时Web Workers的工作例子:
创建一个 worker.ts数字 :
import {
initPhoton,
PhotonImage,
SamplingFilter,
resize,
} from "@cf-wasm/photon/others";
import { register, withOptions } from "@deox/worker-rpc/register";
const registered = register(async () => {
// The wasm must be initialized first, you can provide photon wasm binaries from any source
await initPhoton({
module_or_path: new URL("@cf-wasm/photon/photon.wasm", import.meta.url),
});
return {
resize: async (source: string, format?: "webp" | "png" | "jpeg") => {
// fetch the source image and get bytes
const imageBytes = new Uint8Array(
await (await fetch(source)).arrayBuffer(),
);
// create a PhotonImage instance
const inputImage = PhotonImage.new_from_byteslice(imageBytes);
// resize image using photon
const outputImage = resize(
inputImage,
inputImage.get_width() * 0.5,
inputImage.get_height() * 0.5,
SamplingFilter.Nearest,
);
let outputBytes: Uint8Array;
switch (format) {
case "png":
// get png bytes
outputBytes = outputImage.get_bytes();
break;
case "jpeg":
// get jpeg bytes
outputBytes = outputImage.get_bytes_jpeg(1);
break;
default:
// get webp bytes
outputBytes = outputImage.get_bytes_webp();
}
// Explicitly free rust memory
outputImage.free();
inputImage.free();
// transfer bytes to main thread
return withOptions(outputBytes, [outputBytes.buffer]);
},
};
});
export type Registered = typeof registered;
现在你可以在你的入口处使用:
import { Worker } from "@deox/worker-rpc";
import type { Registered } from "./worker";
const worker = new Worker<Registered>(
new URL("./worker", import.meta.url),
undefined,
);
const element = document.getElementById("demo_image") as HTMLImageElement;
worker.proxy
.resize("https://avatars.githubusercontent.com/u/100576030")
.then((bytes) => {
const url = URL.createObjectURL(new Blob([bytes]));
element.src = url;
});
文档
为了探索所有功能,访问 正式文件。 。 。 .
报告问题
这个图书馆是一个叉子 silvia-odwyer/photon,因此考虑在此开始讨论问题或专题请求.
对于WebAssembly相关议题,您可在此存储器中打开一个议题.
优秀项目
以下是使用此库构建的项目列表:
- 下一个图像处理 API (按 约文·克姆兰尼(中文(简体) )
贷项
所有功劳都归于 @silvia-odwyer/图片。 。 。 .