# WASM Image Processor

The `azion/wasm-image-processor` module is the Azion Lib library for image processing. It uses WebAssembly to load an image from a URL, resize it, and return it as a `Response` in JPEG, PNG, or WebP format. It makes no API calls and needs no token.

Install the package:

```bash
npm install azion
```

The `azion` package receives bug fixes only, and its maintenance ends in December 2026.

[loadImage](#loadimage) returns a [WasmImage](#wasmimage) object, and [resize](#resize), [getImageResponse](#getimageresponse), and [clean](#clean) are its methods. The functions return their result directly and throw an error when they fail. `loadImage` is also the default export of the module.

The module runs in Node.js, and it runs inside a function served locally with [azion dev](/en/documentation/devtools/cli/dev-command/). The samples of the four functions are TypeScript ES modules that use top-level `await`, and they run in Node.js. They import types with `import type`.

---

## loadImage

Fetches an image over HTTP and loads it into a `WasmImage` object.

```typescript
function loadImage(pathOrURL: string): Promise<WasmImage>;
```

| Parameter   | Type     | Required | Description                                                                                                         |
| ----------- | -------- | -------- | ------------------------------------------------------------------------------------------------------------------- |
| `pathOrURL` | `string` | Yes      | The URL of the image. The path of the URL must end in a file extension: `.jpg`, `.jpeg`, `.png`, `.gif`, or `.bmp`. |

Returns a promise of a [WasmImage](#wasmimage). The function refuses a URL whose path does not end in one of those file extensions, such as `/image/png`, and it throws when the server answers with an error status. The parameter name mentions a path, but in Node.js a local file path fails with `TypeError: fetch failed`. The messages are in [Errors](#errors).

This sample loads a PNG image and prints its size:

```typescript
import { loadImage } from 'azion/wasm-image-processor';
import type { WasmImage } from 'azion/wasm-image-processor';

const image: WasmImage = await loadImage('https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png');
console.log(`Loaded ${image.width()}x${image.height()}`);
```

Output:

```text
Loaded 272x92
```

---

## resize

Resizes an image. A method of [WasmImage](#wasmimage).

```typescript
resize(width: number, height: number, usePercent?: boolean): WasmImage;
```

| Parameter    | Type      | Required | Description                                                                                                                            |
| ------------ | --------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `width`      | `number`  | Yes      | The width to resize to. A multiplier of the current width (`0.5` is half) when `usePercent` is `true`, or pixels when it is `false`.   |
| `height`     | `number`  | Yes      | The height to resize to. A multiplier of the current height (`0.5` is half) when `usePercent` is `true`, or pixels when it is `false`. |
| `usePercent` | `boolean` | No       | How `width` and `height` are read. Default: `true`.                                                                                    |

Returns a new [WasmImage](#wasmimage) with the resized image. The original image keeps its size.

With the default `usePercent`, `1` is 100% of the current size: `0.5` halves the image, and `50` makes it 50 times larger. A 272 × 92 image resized with `resize(50, 50)` becomes 13600 × 4600. Pass `false` as the third argument to give the size in pixels.

This sample resizes an image to half its size, then to 100 × 34 pixels:

```typescript
import { loadImage } from 'azion/wasm-image-processor';
import type { WasmImage } from 'azion/wasm-image-processor';

const image: WasmImage = await loadImage('https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png');
const half: WasmImage = image.resize(0.5, 0.5); // usePercent defaults to true: 0.5 = 50%
console.log(`resize(0.5, 0.5): ${half.width()}x${half.height()}`);
const fixed: WasmImage = image.resize(100, 34, false); // pixels
console.log(`resize(100, 34, false): ${fixed.width()}x${fixed.height()}`);
```

Output:

```text
resize(0.5, 0.5): 136x46
resize(100, 34, false): 100x34
```

---

## getImageResponse

Encodes an image in a format and returns it as a `Response`. A method of [WasmImage](#wasmimage).

```typescript
getImageResponse(format: SupportedImageFormat, quality?: number): Response;
```

| Parameter | Type                                            | Required | Description                                               |
| --------- | ----------------------------------------------- | -------- | --------------------------------------------------------- |
| `format`  | [`SupportedImageFormat`](#supportedimageformat) | Yes      | The format of the image: `'jpeg'`, `'png'`, or `'webp'`.  |
| `quality` | `number`                                        | No       | The quality of the image, for `'jpeg'`. Default: `100.0`. |

Returns a [Response](/en/documentation/devtools/runtime/api-reference/response/) with status `200`, the encoded image as its body, and the `content-type` header of the format: `image/jpeg`, `image/png`, or `image/webp`. A function can return this response as it is.

This sample encodes an image as WebP and prints the status, the content type, and the size of the body:

```typescript
import { loadImage } from 'azion/wasm-image-processor';
import type { WasmImage, SupportedImageFormat } from 'azion/wasm-image-processor';

const image: WasmImage = await loadImage('https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png');
const format: SupportedImageFormat = 'webp';
const imageResponse: Response = image.getImageResponse(format);
console.log(imageResponse.status, imageResponse.headers.get('content-type'), (await imageResponse.arrayBuffer()).byteLength, 'bytes');
```

Output:

```text
200 image/webp 9056 bytes
```

---

## clean

Frees the memory that holds an image. A method of [WasmImage](#wasmimage).

```typescript
clean(): void;
```

The method takes no parameters and returns nothing. After `clean()`, the image cannot be used: a call such as `getImageResponse` throws `null pointer passed to rust`. A `Response` that `getImageResponse` returned before `clean()` stays readable, so call `clean()` last.

This sample encodes an image as JPEG, frees the image, then reads the response:

```typescript
import { loadImage } from 'azion/wasm-image-processor';
import type { WasmImage } from 'azion/wasm-image-processor';

const image: WasmImage = await loadImage('https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png');
const response = image.getImageResponse('jpeg'); // use the image first
image.clean(); // then free its memory; the image cannot be used after this
console.log('cleaned; response still readable:', (await response.arrayBuffer()).byteLength, 'bytes');
```

Output:

```text
cleaned; response still readable: 34984 bytes
```

---

## Resize and convert an image in a function

This function loads a PNG image, resizes it to half its size, and returns it as WebP:

```javascript
import { loadImage } from 'azion/wasm-image-processor';

export default {
  async fetch() {
    const image = await loadImage('https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png');
    const response = image.resize(0.5, 0.5).getImageResponse('webp');
    image.clean();
    return response;
  },
};
```

Served locally with `azion dev`, a request saves the response body to a file and prints the status, the content type, and the size:

```text
$ curl -o image.webp -w '%{http_code} %{content_type} size=%{size_download}\n' http://localhost:3333/img
200 image/webp size=3490
```

The saved file is a WebP image.

---

## Errors

The functions throw these errors. Catch them with `try`/`catch` around the call.

| Message                                                    | Cause                                                                                     | What to do                                                               |
| ---------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| `Invalid image extension. Supported: jpg,jpeg,png,gif,bmp` | The path of the URL passed to `loadImage` does not end in an image extension.             | Use a URL whose path ends in `.jpg`, `.jpeg`, `.png`, `.gif`, or `.bmp`. |
| `Error getting image. Http status code: 404`               | The server of the URL answered with an error status. The message carries the status code. | Check that the URL serves the image.                                     |
| `TypeError: fetch failed`                                  | In Node.js, `loadImage` received a local file path.                                       | Pass the URL of the image.                                               |
| `null pointer passed to rust`                              | The image was used after [clean](#clean).                                                 | Call `clean()` after the last use of the image.                          |

---

## Types

The module exports these types. Import them with `import type`.

### WasmImage

The image that [loadImage](#loadimage) and [resize](#resize) return: a wrapped `PhotonImage` with methods to process it.

| Member                               | Type          | Description                                                                            |
| ------------------------------------ | ------------- | -------------------------------------------------------------------------------------- |
| `image`                              | `PhotonImage` | The `PhotonImage` instance that holds the image data.                                  |
| `width()`                            | `number`      | Returns the width of the image, in pixels.                                             |
| `height()`                           | `number`      | Returns the height of the image, in pixels.                                            |
| `resize(width, height, usePercent?)` | `WasmImage`   | Returns a resized copy of the image. Refer to [resize](#resize).                       |
| `getImageResponse(format, quality?)` | `Response`    | Returns the image encoded in a format. Refer to [getImageResponse](#getimageresponse). |
| `clean()`                            | `void`        | Frees the memory of the image. Refer to [clean](#clean).                               |

### SupportedImageFormat

The formats [getImageResponse](#getimageresponse) encodes.

```typescript
type SupportedImageFormat = 'webp' | 'jpeg' | 'png';
```

---

## Related resources

- [Azion Lib](/en/documentation/devtools/azion-lib.md): The libraries Azion Lib ships and the package that carries each one.
- [How Azion Lib works](/en/documentation/devtools/azion-lib/how-it-works.md): Where each module runs, in Node.js and inside a function.
- [Response](/en/documentation/devtools/runtime/api-reference/response.md): The response object that getImageResponse returns.
- [Azion CLI dev](/en/documentation/devtools/cli/dev-command.md): Serve a function locally and request the images it returns.
