Filters
Brightness, contrast, saturation, sharpness, grayscale, sepia — applied identically to the live preview and the exported image.
| Filter | Type | Valid values | Default |
|---|---|---|---|
brightness | number | >= 0 (1 = unchanged) | 1 |
contrast | number | >= 0 (1 = unchanged) | 1 |
saturation | number | >= 0 (1 = unchanged) | 1 |
sharpness | number | >= 0 (1 or below = unchanged; higher sharpens) | 1 |
grayscale | boolean | true, false | false |
sepia | boolean | true, false | false |
sharpness works differently from the others: unlike
brightness/contrast/saturation, it isn't a native CSS filter — CSS has no
sharpen() function. Kiri generates a small SVG
feConvolveMatrix filter (an unsharp-mask kernel) per instance
and references it via a url(#id) appended to the same filter
string, so it's still just one filter string driving both the live preview
and the export — see Architecture for how.
Setting filters
// initial, via the constructor
new Kiri(container, { filters: { sepia: true } });
// afterward — merges into the current filters
cropper.setFilters({ brightness: 1.2, grayscale: true });
setFilters() merges a partial update into the current
filters (fields you don't pass are left as they are), and clamps numeric
values to >= 0.
Why the preview and export always match
Both the live preview and the canvas export apply the exact same CSS
filter string — the preview via the image element's
style.filter, the export via the canvas 2D context's
ctx.filter before drawing. Reusing the browser's own filter
implementation for both means they're guaranteed to match pixel-for-pixel,
with no separately hand-rolled brightness/contrast/saturation/sharpness
pixel math to get subtly wrong — including sharpness's SVG
filter, since both style.filter and ctx.filter
support the same url(#id) reference syntax identically.