![Oracle Drags Its Feet in the JavaScript Trademark Dispute](https://cdn.sanity.io/images/cgdhsj6q/production/919c3b22c24f93884c548d60cbb338e819ff2435-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Oracle Drags Its Feet in the JavaScript Trademark Dispute
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
@cf-wasm/photon
Advanced tools
High-performance Rust image processing library (Photon) for Cloudflare workers, Next.js and Node.js.
Powered by @silvia-odwyer/photon
Build for commit 941adf9
Forked on: 15th November, 2024
.
npm install @cf-wasm/photon # npm
yarn add @cf-wasm/photon # yarn
pnpm add @cf-wasm/photon # pnpm
Cloudflare Workers / Pages (Esbuild):
import { PhotonImage } from "@cf-wasm/photon";
Next.js Edge Runtime (Webpack):
import { PhotonImage } from "@cf-wasm/photon/next";
Node.js (file base):
import { PhotonImage } from "@cf-wasm/photon/node";
Browser, Web Worker, etc. (experimental)
import { PhotonImage } from "@cf-wasm/photon/others";
Here are some examples in which image is being resized and converted to webp format:
If you are using Cloudflare Workers, you can use it as shown below:
// src/index.ts
import { PhotonImage, SamplingFilter, resize } from "@cf-wasm/photon";
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
);
// 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 the Response instance
return new Response(outputBytes, {
headers: {
"Content-Type": "image/webp"
}
});
}
} satisfies ExportedHandler;
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/next";
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
);
// 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 the Response instance
return new Response(outputBytes, {
headers: {
"Content-Type": "image/webp"
}
});
}
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/next";
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
);
// 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 the Response instance
return new Response(outputBytes, {
headers: {
"Content-Type": "image/webp"
}
});
}
You can use others
submodule and provide wasm binaries using initPhoton
function to make it work on other runtime (i.e. Browser
, Web Worker
, etc).
[!WARNING] The
others
submodule is yet experimental. Breaking changes may be introduced without following semantic versioning.
@deox/cors-worker can make messaging even more easier when using web workers.
Here is a working example for Web Workers when using Webpack bundler:
Create a worker.ts
:
import { initPhoton, PhotonImage, SamplingFilter, resize } from "@cf-wasm/photon/others";
import { register } from "@deox/cors-worker/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 imagBytes = new Uint8Array(
await (await fetch(source)).arrayBuffer()
);
// create a PhotonImage instance
const inputImage = PhotonImage.new_from_byteslice(imagBytes);
// 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();
// create a blob url
return URL.createObjectURL(new Blob([outputBytes]));
}
};
});
export type Registered = typeof registered;
Now you can use it in your entrypoints:
import { Worker } from "@deox/cors-worker";
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((blobUrl) => {
element.src = blobUrl;
});
To explore all the functions, visit the official documentation.
Following is a list of projects built using this library:
All credit goes to @silvia-odwyer/photon.
FAQs
Photon library for Cloudflare workers, Next.js and Node.js.
The npm package @cf-wasm/photon receives a total of 525 weekly downloads. As such, @cf-wasm/photon popularity was classified as not popular.
We found that @cf-wasm/photon demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.