On this page
Fixed-dimension pixel effects such as invert, grayscale, colorize, blur, glow, and shadow, ported byte-for-byte so server-applied effects match the browser exactly.
#server.src.pixelweaver.effects
#server.src.pixelweaver.effects
Server-side pixel effects -- faithful ports of the client effect algorithms.
Mirrors plugins/builtin/effects/*.ts and the HSV helpers in src/lib/color/color-utils.ts. Each effect takes a flat RGBA buffer (width*height*4 bytes) plus its native parameters and returns a NEW buffer of the same dimensions. All rounding uses round-half-up (floor(x + 0.5)) to match JavaScript Math.round.
Fixed-dimension effects are ported here. Dimension-changing / whole-canvas transforms (rotate 90/270, scale) and any effect that cannot be reproduced byte-for-byte are surfaced as a hard error by apply_effect -- never a silent skip (see EFFECT_HARD_ERRORS).
#_round
def _round(x: float) -> intRound half up, matching JS Math.round for the non-negative and negative values these effects produce.
#invert
def invert(buf: _Buf) -> bytearrayInvert the RGB channels (255 - value); alpha is preserved.
#grayscale
def grayscale(buf: _Buf) -> bytearrayConvert each pixel to its Rec. 601 luminance (0.299R + 0.587G + 0.114B); alpha is preserved.
#colorize
def colorize(buf: _Buf, color: str) -> bytearrayTint each pixel toward color scaled by its own luminance; fully transparent pixels pass through unchanged.
#brightness_contrast
def brightness_contrast(buf: _Buf, brightness: float, contrast: float) -> bytearrayApply a per-channel brightness offset and contrast factor (the standard 259-based contrast formula); alpha is preserved.
#hue_shift
def hue_shift(buf: _Buf, degrees: float) -> bytearrayRotate each pixel's hue by degrees in HSV space; fully transparent pixels pass through unchanged.
#blur
def blur(buf: _Buf) -> bytearray1px box blur (average of self + in-bounds 8-neighbors).
#sharpen
def sharpen(buf: _Buf, amount: float=1.0) -> bytearrayUnsharp mask: original + (original - blurred) * amount, alpha preserved.
#flip
def flip(buf: _Buf, direction: str) -> bytearrayMirror the buffer horizontally (direction == "h") or vertically (direction == "v").
#outline
def outline(buf: _Buf, thickness: int, color: str) -> bytearrayFill transparent pixels within Chebyshev thickness of an opaque pixel with the outline color. Starts from a copy of the buffer.
#glow
def glow(buf: _Buf, radius: int, color: str, opacity: float) -> bytearrayPaint a color glow into transparent pixels within radius of an opaque pixel, with linear distance falloff scaled by opacity.
#shadow
def shadow(buf: _Buf, offset_x: int, offset_y: int, color: str, opacity: float) -> bytearrayCast a color drop shadow at opacity, offset by (offset_x, offset_y), into transparent pixels that do not overlap opaque source pixels.
#UnsupportedEffectError
An effect that is not (yet) faithfully portable via this path.
#apply_effect
def apply_effect(data: bytes, width: int, height: int, effect: str, params: dict[str, Any]) -> bytesApply effect to an RGBA buffer and return a new buffer.
Raises UnsupportedEffectError for dimension-changing effects and unknown effect names -- never a silent skip.