For plugin makers

Make a plugin for Cloud Photo

A plugin adds a filter to Cloud Photo’s Filter menu. It gets pixels and settings, and changes the pixels. The result goes on a new layer above the original.

Download the kit (zip, 11 KB) Try the sample

The kit has this guide, a sample plugin and a script that builds it.

One file

  • A .cloudphoto-plugin file is a zip with two files: manifest.json and plugin.wasm
  • People install it with File › Plugins, and it shows in Filter › Plugin

Any language

  • The filter is WebAssembly, so any language that compiles to it will do
  • The kit’s build script compiles AssemblyScript, which reads like TypeScript

Kept to its pixels

  • A plugin gets the pixels and nothing else: no internet, files or account
  • Cloud Photo draws its controls, and the original layer always stays

Plugins work in Cloud Photo in the browser and on Windows from version 1.8.0. The Mac gets them in its next update.

Try the sample

You need Node.js 22.2 or later. Unzip the kit, then in its folder run:

npm install assemblyscript
node build.mjs sample

That makes sample/sample.cloudphoto-plugin. In Cloud Photo, choose File › Plugins, then Install a plugin, and pick the file. Soft glow is now in the Filter menu.

To make your own, copy the sample folder, change manifest.json and plugin.ts, and run node build.mjs with your folder’s name.

manifest.json

What the plugin is called and which controls it has.

FieldNeededWhat it is
formatYes1
idYesLetters, digits, ., _ and -, up to 64. A new version keeps it.
nameYesUp to 40 characters, shown in the Filter menu
versionYesUp to 20 characters
authorNoUp to 60 characters
descriptionNoUp to 300 characters
marginNoHow far your filter looks past a pixel, 0 to 256 (see Tiles)
settingsNoUp to 16 controls, drawn by Cloud Photo

Each setting has a label (up to 40 characters) and a type:

typeOther fieldsValue your plugin gets
slidermin, max, step, defaultThe number
checkboxdefault (true or false)1 or 0
colordefault ("#rrggbb")The number 0xRRGGBB

A plugin can’t draw controls or screens of its own. The sample’s manifest:

{
  "format": 1,
  "id": "com.mycloudsuites.sample.soft-glow",
  "name": "Soft glow",
  "version": "1.0.0",
  "author": "MyCloudSuites",
  "description": "The sample plugin: spreads the light parts of a picture.",
  "margin": 32,
  "settings": [
    { "type": "slider", "label": "Radius", "min": 1, "max": 32, "step": 1, "default": 8 },
    { "type": "slider", "label": "Strength", "min": 0, "max": 100, "step": 1, "default": 50 },
    { "type": "checkbox", "label": "Tint the glow", "default": false },
    { "type": "color", "label": "Tint", "default": "#ffcc88" }
  ]
}

What the module must do

It must import its memory as env.memory and import nothing else. It must not define a memory of its own. A module that does either is refused when someone installs it.

It must export these three functions:

// Called once for each setting, in manifest order, before any pixels.
// Needed only with settings.
setting(index: i32, value: f64): void

// Makes room for `bytes` bytes of pixels and returns where they go. Called once.
// Grow the memory here if you need to. The memory can reach 1 GB.
buffer(bytes: i32): i32

// Changes w × h pixels at `ptr` in place: RGBA rows, 8 bits a channel, not
// premultiplied, with no gaps between rows. (x, y) is where these pixels are
// in a W × H picture. Called once for each tile.
// Return 0, or any other number to say something went wrong.
filter(ptr: i32, w: i32, h: i32, x: i32, y: i32, W: i32, H: i32): i32

Tiles

Large pictures arrive a tile at a time, up to 1024 × 1024 pixels plus margin on each side, and only the tile itself is kept. If your filter looks up to 32 pixels away, set margin to at least 32 and no seams will show.

buffer is called once, for the largest tile, so filter can get smaller ones after it. Your variables stay between tiles.

The preview runs your filter on a smaller copy of the picture, so effects measured in pixels look stronger there.

Limits

  • The file can be up to 32 MB.
  • A plugin that doesn’t finish a tile within 60 seconds is stopped, and nothing changes.
  • If the plugin fails, returns a number other than 0 or doesn’t make room, nothing changes.
  • Pixels are 8 bits a channel, including those from 16-bit layers. The original layer keeps its 16.
  • In the browser, a plugin is kept in that browser and doesn’t follow the person’s account.

Questions

How do people get my plugin?

Share the .cloudphoto-plugin file however you like, on your website or by email. There’s no plugin store in Cloud Photo.

What do people see when they install it?

Its name, version, author and description, and a reminder that MyCloudSuites hasn’t checked it, and that it can only change the pixels it’s given. Installing a new version with the same id replaces the old one.

Can a plugin make a whole new tool?

Not yet. A plugin is a filter: it changes a layer’s pixels, or the pixels inside a selection, with the controls in its manifest.

Something isn’t working. Who do I ask?

Tell us what you tried and what happened.

Make your first filter.

The kit builds the sample in two commands.

Download the kit About Cloud Photo