BoxLang 🚀 A New JVM Dynamic Language Learn More...
AVIF is a ColdBox module that provides a simple API for converting
images into AVIF
format, decoding AVIF images back into PNG/JPEG, and inspecting AVIF
files. It uses the precompiled libavif
command-line binaries (avifenc / avifdec).
It is a hot-swap sister module to webp
: the API mirrors the webp module's methods and
shared argument names, so a consuming app (like a CMS) can switch
webp@webp for avif@avif with no call-site
changes — only the output file extension changes.
AVIF is a modern, royalty-free image format based on the AV1 video codec. It typically achieves smaller files than both JPEG and WebP at comparable quality, supports alpha transparency, wide color gamut, and high bit depth. It is supported by all major modern browsers.
Neither Adobe ColdFusion nor Lucee ship native AVIF encoding. This module fills that gap by driving the official libavif binaries, so both engines can produce and consume AVIF without built-in image support.
box install avif
The module detects your platform and points at the bundled binaries.
To override (e.g. to use your own libavif build), set module settings
in your Coldbox.cfc:
moduleSettings = {
avif = {
avifencPath : "C:\tools\libavif\avifenc.exe", // explicit encoder path
avifdecPath : "C:\tools\libavif\avifdec.exe", // explicit decoder path
timeout : 90, // default seconds before a conversion is killed
maxDimension : 16384 // decode guard (avifdec --dimension-limit); 0 = off
}
};
Alternatively, override just the folder that contains the binaries
via binPath.
Inject the model with WireBox:
property name="avif" inject="avif@avif";
Encode an image into AVIF:
avif.encode(
source = "path/to/image.jpg",
destination = "path/to/image.avif"
);
Decode an AVIF image into another format (PNG or JPEG — unlike WebP, JPEG is supported directly):
avif.decode(
source = "path/to/image.avif",
destination = "path/to/image.png"
);
Get information about an AVIF image:
var meta = avif.info( source = "path/to/image.avif" );
// meta.width, meta.height, meta.depth, meta.alpha, meta.chroma, ...
Supported decode output formats: PNG, JPEG, Y4M (inferred from the destination extension).
webp moduleBecause the shared argument names match, the same call site works against either module:
// Works identically whether `img` is webp@webp or avif@avif:
img.encode( source = upload, destination = target, quality = 80, resizeWidth = 800 );
avifenc/avifdec cannot crop or resize raster
pixels themselves, so this module performs
cropX/Y/Width/Height and
resizeWidth/resizeHeight (and flipImage on
decode) using ColdFusion's native cfimage functions —
giving you the same behavior a CMS expects from the webp module.
| Argument | Type | Default | Description |
|---|---|---|---|
source
| string | Full path to the source file (JPEG/PNG/Y4M) | |
destination
| string | Full path to the
.avif output | |
quality
| int (0-100) | 80 | Color quality; 100 ≈
lossless (avifenc -q) |
lossless
| boolean | false | Encode losslessly
(avifenc -l) |
alphaQuality
| int (0-100) | Alpha channel quality
(avifenc --qalpha) | |
cropX/Y/Width/Height
| int | Pixel crop (all four together; via cfimage) | |
resizeWidth
| int | 0 | Resize width; 0 preserves aspect
ratio (via cfimage) |
resizeHeight
| int | 0 | Resize height; 0 preserves aspect
ratio (via cfimage) |
multiThreaded
| boolean | true | Use all worker threads
(avifenc -j all) |
metadata
| string | "none"
strips EXIF/XMP/ICC; otherwise preserved | |
overwrite
| boolean | true | Replace an existing destination |
verbose
| boolean | false | Accepted for parity; output is always captured |
timeout
| int | 0 | Seconds before the process is killed (0 = module setting) |
speed
| int (0-10) | 6 | Encoder speed/effort; 0
slowest/best (avifenc -s) |
depth
| int (8/10/12) | Output bit depth
(avifenc -d) | |
chroma
| string | auto/444/422/420/400
(avifenc -y) |
Hot-swap note: WebP-specific options (
nearLossless,preset,compressionMethod,filterStrength,jpegLike,sourceHint, …) have no AVIF equivalent. You can leave them in a hot-swapped call — CFML simply ignores arguments this module doesn't declare, so nothing breaks; they just have no effect.
| Argument | Type | Default | Description |
|---|---|---|---|
source
| string | Full path to the
.avif source | |
destination
| string | Output path (.png,
.jpg, .jpeg, .y4m) | |
quality
| int (0-100) | 90 | JPEG output quality (JPEG
destinations only, avifdec -q) |
depth
| int (8/16) | PNG output depth (PNG
destinations only, avifdec -d) | |
upsampling
| string | automatic | Chroma upsampling
(avifdec -u) |
cropX/Y/Width/Height
| int | Pixel crop (via cfimage) | |
resizeWidth/resizeHeight
| int | 0 | Resize; 0 preserves aspect ratio
(via cfimage) |
flipImage
| boolean | false | Flip vertically (via cfimage) |
multiThreaded
| boolean | true | Use all worker threads
(avifdec -j all) |
overwrite
| boolean | true | Replace an existing destination |
verbose
| boolean | false | Accepted for parity; output is always captured |
timeout
| int | 0 | Seconds before the process is killed (0 = module setting) |
info( source ) → struct guaranteed to include numeric
width and height, plus depth,
alpha, chroma, and the raw parsed keys
(Resolution, BitDepth,
Format, Range, …). Pass
verbose=true to include rawOutput.version() → struct with backend, binary
paths, avifencVersion, avifdecVersion,
platform, bundled.capabilities() → struct describing supported formats
and features.Failures throw typed exceptions you can catch by type:
try {
avif.encode( source = src, destination = dest );
} catch ( "avif.binaryExecutionFailed" e ) {
// e.detail contains the tool output
} catch ( "avif.timeout" e ) {
// conversion exceeded the timeout
}
Types: avif.unsupportedPlatform,
avif.binaryNotFound,
avif.binaryExecutionFailed, avif.timeout,
avif.invalidSource, avif.invalidDestination,
avif.unsupportedFormat. Output is written atomically (to
a temp file, then moved on success), so a failed conversion never
leaves a partial destination file behind.
Binaries are executed directly with Java ProcessBuilder
— no shell is invoked — and every argument is passed
as a discrete value, so filenames containing spaces,
&, (, ) etc. are handled
safely and cannot be interpreted as flags or shell metacharacters. For
untrusted uploads, keep the maxDimension decode guard enabled.
avif.unsupportedPlatform at load.
macOS/Linux support is a matter of bundling the corresponding
libavif binaries and extending the resolver.cfimage (native
ColdFusion image functions), not by the AVIF tools.This module bundles the libavif command-line tools. See THIRD-PARTY-NOTICES.md for libavif / aom / dav1d license and attribution details.
Apache-2.0. See LICENSE.
Developed by Angry Sam Productions, a freelance web design and development company. We contribute to open source to strengthen the development community. Get in touch to learn more or to hire us for your next project.
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
encode() — JPEG/PNG/Y4M → AVIF via bundled avifenc (libavif 1.4.2).decode() — AVIF → PNG/JPEG/Y4M via bundled avifdec (JPEG output supported
directly, an improvement over the webp sister module).info() — normalized metadata struct guaranteeing width/height.version() and capabilities() helper methods.webp module: shared argument names for
the options both formats support.cfimage, since libavif tools do not perform raster transforms.speed, depth, chroma, alphaQuality, upsampling.ProcessBuilder (no shell) for safe handling of
paths with spaces/special characters.
$
box install avif