@cf-wasm/png

中文文档
0.4.0发布于 2026/08/01MITTypeScriptES Module零依赖构建来源已验证近 30 天下载 3.4万

A simple wasm png encoder/decoder module for cloudflare workers

原始使用文档
文档目录10 节
  1. Installation
  2. Usage
  3. API
  4. encode
  5. decode
  6. Examples
  7. Cloudflare Workers
  8. Next.js (App Router)
  9. Next.js (Pages Router)
  10. Credits

@cf-wasm/png

A simple wasm png encoder/decoder module for Cloudflare Workers, Next.js and Node.

Powered by denosaurs/pngs.

Installation

npm install @cf-wasm/png       # npm
yarn add @cf-wasm/png          # yarn
pnpm add @cf-wasm/png          # pnpm

Usage

Because package.json includes conditional exports for node, workerd, and edge-light, you can usually import directly from @cf-wasm/png and let the runtime choose the correct entrypoint:

import { encode } from "@cf-wasm/png";

If you want to be explicit, import from a submodule instead:

  • Cloudflare Workers / Pages (Wrangler):

    import { encode } from "@cf-wasm/png/workerd";
    
  • Next.js Edge Runtime:

    import { encode } from "@cf-wasm/png/edge-light";
    
  • Node.js (inline):

    import { encode } from "@cf-wasm/png/node";
    

API

encode

The encode function encodes an input Uint8Array representing an image into a PNG format.

const encode: (
  image: Uint8Array,
  width: number,
  height: number,
  options?: EncodeOptions,
) => Uint8Array;

decode

The decode function decodes an input Uint8Array representing a PNG image.

const decode: (image: Uint8Array) => {
  image: Uint8Array;
  width: number;
  height: number;
  colorType: number;
  bitDepth: number;
  lineSize: number;
};

Examples

Here are some examples for using this library.

Cloudflare Workers

If you are using Cloudflare Workers, you can use it as shown below:

// src/index.ts
import { PhotonImage, SamplingFilter, resize } from "@cf-wasm/photon/workerd";
import { encode } from "@cf-wasm/png/workerd";

export default {
  async fetch() {
    // url of image to fetch
    const imageUrl = "https://avatars.githubusercontent.com/u/314135";

    // fetch image and get the Uint8Array instance
    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,
    );

    // encode using png
    const outputBytes = encode(
      outputImage.get_raw_pixels(),
      outputImage.get_width(),
      outputImage.get_height(),
    );

    // call free() method to free memory
    inputImage.free();
    outputImage.free();

    // return the Response instance
    return new Response(outputBytes, {
      headers: {
        "Content-Type": "image/png",
      },
    });
  },
} satisfies ExportedHandler;

Next.js (App Router)

If you are using Next.js (App router) with edge runtime, you can use it as shown below:

// (src/)app/api/image/route.ts
import { type NextRequest } from "next/server";
import {
  PhotonImage,
  SamplingFilter,
  resize,
} from "@cf-wasm/photon/edge-light";
import { encode } from "@cf-wasm/png/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 Uint8Array instance
  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,
  );

  // encode using png
  const outputBytes = encode(
    outputImage.get_raw_pixels(),
    outputImage.get_width(),
    outputImage.get_height(),
  );

  // call free() method to free memory
  inputImage.free();
  outputImage.free();

  // return the Response instance
  return new Response(outputBytes, {
    headers: {
      "Content-Type": "image/png",
    },
  });
}

Next.js (Pages Router)

If you are using Next.js (Pages router) with edge runtime, you can use it as shown below:

// (src/)pages/api/image.ts
import { type NextRequest } from "next/server";
import {
  PhotonImage,
  SamplingFilter,
  resize,
} from "@cf-wasm/photon/edge-light";
import { encode } from "@cf-wasm/png/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 Uint8Array instance
  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,
  );

  // encode using png
  const outputBytes = encode(
    outputImage.get_raw_pixels(),
    outputImage.get_width(),
    outputImage.get_height(),
  );

  // call free() method to free memory
  inputImage.free();
  outputImage.free();

  // return the Response instance
  return new Response(outputBytes, {
    headers: {
      "Content-Type": "image/png",
    },
  });
}

Credits

All credit goes to denosaurs/pngs.

版本与发布记录

@cf-wasm/png 共发布 33 个版本,首次发布于 2023/11/22;过去 12 个月发布了 7 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.4.0latest2026/08/013 个月前
0.3.42026/07/143 个月前
0.3.32026/05/046 个月前
0.3.22025/12/0411 个月前
0.3.12025/11/2611 个月前
0.3.02025/11/2511 个月前

关于 @cf-wasm/png 的常见问题

@cf-wasm/png 是什么?

A simple wasm png encoder/decoder module for cloudflare workers

如何安装 @cf-wasm/png?

在项目目录运行 npm install @cf-wasm/png,或使用 pnpm add / yarn add / bun add。

@cf-wasm/png 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@cf-wasm/png 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@cf-wasm/png 可以商用吗?

@cf-wasm/png 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@cf-wasm/png 的下载量有多少?

根据 npm 官方下载统计,@cf-wasm/png 在 2026/10/10 – 2026/11/08 这 30 天内被下载 34,161 次,日均约 1,139 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@cf-wasm/png 还在维护吗?

最新版本 0.4.0 发布于 2026/08/01(3 个月前);至今共发布 33 个版本,其中过去 12 个月发布了 7 个;首次发布于 2023/11/22。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。