Image API

Contents

The Image API provides real-time processing and delivery of raster images from media content.

Location

By default, the Image API is available at:

8080:/api/media:image/

The exact public URL can differ per environment based on virtual host configuration, which is commonly used to expose the API on a friendlier path — for example https://media.example.com/image/.

URLs to the Image API is usually generated by using the Guillotine API, imageUrl field.

Enonic app developers may use the Portal API, imageUrl function

URL structure

An image URL consists of the following components:

  1. Base URL
    :8080/api/media:image/

  2. Media Locator with an optional (branch)
    <project>(:<branch>)/<content-id>
    Branch is specified only if it is not master (published content). Specifying master branch is an error - to avoid cache pollution. Since we only have master and draft there are only two options: /<project>/ and /<project>:draft/

  3. (Optional) fingerprint
    :<image-fingerprint> - the fingerprint of the image.
    If fingerprint is not supplied the response will not contain "immutable" Cache-Control header.

  4. Scaling (method followed by arguments, separated by dashes), followed by a forward slash.
    Example: block-300-100/

  5. File name equal to content name.
    Example: content-name.png

  6. (Optional) Format extension, preceded by a period.
    Example: .jpg

  7. URL parameters, such as background or filter (URI encoded, filter values are semicolon-separated)
    Example: ?background=0x777777&filter=sharpen%28%29%3Brounded%2820%2C3%29

If format extension is specified, content gets converted to a corresponding format. Otherwise, the MIME type is derived directly from the content.
Supported format extensions are .jpg, .png and .gif. Other extensions may still work but are not supported.
Content with MIME type image/gif and image/svg+xml are returned as-is without any processing.

Example of an image URL on the root of a live site behind a Virtual Host:

/media:image/myproject/c82262a6-77d6-4276-b0e7-fe82f4eb57b8:1feb57ed672f8c3b9fd6d4614878dafd9882298b/block-300-100/content-name.png.jpg?background=0x777777&filter=sharpen%28%29%3Brounded%2820%2C3%29

Media scope

You may limit which projects and branches are accessible by mounting the API in a Virtual Host.

Use the setting endpoint.media.scope = <project1:draft>, <project2> in the Virtual Host Context.

Scaling methods

Block

Scaled to block

Scales the image to fill the given dimensions, then crops off any overflowing content based on the focal point position. This is the most common scaling method for web purposes, since the image will always have the exact dimensions as the given input.

Arguments

Both arguments below are required:

width

Width in pixels

height

Height in pixels

Example
block-300-100

Height

Scaled to height

Scales the image proportionally to match the given height. No cropping. Width may vary depending on aspect ratio.

Arguments
height

Height in pixels

Example
height-300

Max

Scaled to max

Scales the image proportionally until the longest edge has the given number of pixels. Typically used if the image will be displayed inside a square container but must not be cropped (e.g. diagrams or logo images that must fit inside a square table cell)

Arguments
size

The length of the longest edge in pixels. Required.

Example
max-300

Square

Scaled to square

Scales the image proportionally to match the shortest edge, resulting in a square image. Any overflowing content will be cropped based on the focal point position.

Arguments
size

The length of both sides in pixels

Example
square-300

Wide

Scaled to wide

Similar to scale Block, but will never crop off the left/right sides of the image. The resulting image would always be as wide as the given width, but if the image has a wider aspect ratio than given, it would end up being lower than the given height.

Arguments
width

Width in pixels

height

Maximum height in pixels

Example
wide-300-100

Width

Scaled to width

Scales the image proportionally to match the given width. No cropping. Height may vary depending on aspect ratio.

Arguments
width

Width in pixels

Example
width-300

Full

No scaling

Example
full

Filters

Some (but not all) of the filters below perform under-the-hood calculations measured in pixels, which means that images of various dimensions will have the effect applied differently. This is especially apparent if the images are forced to fit a specific container size on the client. In order to ensure a consistent result, consider upscaling your image to a specific size before applying the filter, or downscale if the effect should be larger in relation to the image.

RGB Adjust

RGB Adjust towards orange

Adjust the red, green and blue levels in the image.

Values between -1.0 and 0.0 subtract that color channel in the image. A value of 0 results in no adjustment for that channel. Values between 0 and 255 boosts that color channel in the image. The boost is logarithmic, so small boost values between 0 and 1 are often enough.

Arguments
red

Decimal value with the adjusted red level for the image. Required.

green

Decimal value with the adjusted green level for the image. Required.

blue

Decimal value with the adjusted blue level for the image. Required.

Example
rgbadjust(0.0,-1.0,-1.0) (1)
rgbadjust(0.0,0.0,-1.0) (2)
rgbadjust(1.0,0.0,-1.0) (3)
1 Red channel only, otherwise black
2 No blue channel, otherwise unmodified
3 No blue channel, boosted red channel (as seen in the image above)

HSB Adjust

HSB Adjust to oppsite colors

Adjust the hue, saturation and brightness levels in the image.

This effect is a lot more rudimentary than the Hue/Saturation effect in Photoshop. For instance, when reducing saturation, all colors below a certain threshold are strictly converted to grayscale instead of being desaturated. The use of values outside of +/-0.2 is not recommended.
Arguments
hue

Decimal value from -1 to 1, of how far around the color wheel to move the hue of the image. Required. (0 is no change)

saturation

Decimal value from -1 to 1 to adjust the intensity of the colors in the image. Default: 0

brightness

Decimal value from -1 to 1 to adjust the brightness of the image. Default: 0

Examples
hsbadjust(-0.15,0.2,-0.2)

Block

Blocks 5 pixels large

Reduces the image down to a mosaic of larger square pixels. Also known as pixelate.

Arguments
size

The size of each square mosaic block, in pixels. Default: 2

Example
block(5)

Blur

8 pixel blur

Applies a Gaussian blur-like effect, based on the given pixel radius. The opposite of Sharpen, although it’s not possible to reverse a sharpen with a blur.

Arguments
radius

How many pixels of blur to apply. Higher values lead to a more blurry image, values below 2 result in no blur. Default: 2

Example
blur(8)

Border

Solid gray 4 pixel border

Applies a rectangular border with a solid color around the image.

Arguments
width

The width of the border in pixels. Default: 2

color

The color of the border as a decimal or hexadecimal number. Default: 0x000000 (black)

Examples
border(5)
border(4, 0x777777)

Bump

Bump effect

Creates a pseudo-3D bevel effect based on edge contours in the image.

Arguments

No arguments

Example
bump()

Colorize

Colorize to magenta

Makes a grayscale image, then applies a tint based on the color given with red, green and blue values.

Arguments
red

Red boost value. Default: 1

green

Green boost value. Default: 1

blue

Blue boost value. Default: 1

Example
colorize(3,1,1.5)

HSB Colorize

Colorize to cyan

Makes a grayscale image, then applies a tint based on the color given with hue, saturation, and brightness.

Arguments
color

The tint color as a decimal or hexadecimal number. Default: 0xFFFFFF

Example
hsbcolorize(0x00AAAA)

Edge

Edge effect

Creates an abstract image by brightening every edge contour and darkening every even surface of the image.

Arguments

No arguments

Example
edge()

Emboss

Emboss effect

Creates a grayscale image with a pseudo-3D bevel effect based on edge contours in the image. Areas with no contours are normalized to a neutral gray. If colors need to be kept as they were, consider using Bump instead.

Arguments

No arguments

Example
emboss()

Flip horizontally

Flipped horizontally

Flips an image horizontally (mirrored left-right).

Arguments

No arguments

Example
fliph()

Flip vertically

Flipped vertically

Flips an image vertically (mirrored upside down, like a water reflection).

Arguments

No arguments

Example
flipv()

Grayscale

Grayscale effect

Creates a grayscale variant of the image.

Use an adjustment filter in front of the grayscale filter in order to affect how bright or dark different portions of the image will be, e.g. to highlight skin tones.
Arguments

No arguments

Example
grayscale()

Invert

Inverted colors

Inverts the colors and brightness of the image.

The human eye does not have a linear response across the whole visible spectrum, so inverting the image may have unexpected effects on text contrast in relation to the processed image.
Arguments

No arguments

Example
invert()

Rotate 90

Rotated 90 degrees

Rotates an image clockwise 90 degrees. Width and height dimensions get swapped, e.g. a 200x100 pixel image becomes 100x200 pixels.

Arguments

No arguments

Example
rotate90()

Rotate 180

Rotated 180 degrees

Rotates an image 180 degrees.

Arguments

No arguments

Example
rotate180()

Rotate 270

Rotated 270 degrees

Rotates an image clockwise 270 degrees (i.e. counter-clockwise 90 degrees). Width and height dimensions get swapped, e.g. a 200x100 pixel image becomes 100x200 pixels.

Arguments

No arguments

Example
rotate270()

Rounded

Rounded corners with added border

Rounds the corners of the image, with an option of adding a border around the rounded image which also has rounded corners.

To create a circular image, apply a scale square at a desired number of pixels for the diameter, and then apply rounded with radius set to half that amount of pixels for the radius.
If the image format has been set to PNG, the negative space outside the rounded corners is rendered as transparent. If the image format has been set to JPG, the negative space outside the rounded corners is rendered as the background color.
Arguments
radius

The number of pixels from each corner where the rounding starts. Default: 10

borderSize

The width of the border in pixels. Default: 0

borderColor

The color of the border as a decimal or hexadecimal number. Default: 0 / 0x000000 (black)

Examples
rounded()
rounded(15)
rounded(10,1)
rounded(8,4,0x777777)

Sepia

Sepia effect

Creates a grayscale image with a yellow-reddish tint to make it look like an old photograph.

Arguments
depth

The brightness of the tint. Default: 20

Examples
sepia()
sepia(25)

Sharpen

Sharpen effect

Applies a sharpening filter to the image, making edge contours more pronounced. The opposite of Blur, although it’s not possible to reverse a blur with a sharpen.

If the source image has a lot of compression artifacts or has very low resolution, sharpening the image will make these artifacts stand out even more, which usually is undesired.
Arguments

No arguments

Example
sharpen()

Response

A successful response streams the rendered image in the body. The API accepts GET, HEAD, and OPTIONS — any other method returns 405 Method Not Allowed.

Unlike the Attachment API, the Image API does not support range requests. Each scaled+filtered rendition is generated on demand from the source image and meant to be cached as a single immutable resource — there is no Accept-Ranges header, and Range request headers are ignored.

Status codes

200 OK

The rendered image is returned in the body.

400 Bad Request

Invalid scaling arguments or query parameters (filter, quality, background).

404 Not Found

Content does not exist, is not an image, or the underlying source attachment cannot be resolved.

429 Too Many Requests

The image service is throttling — too many concurrent render operations. Clients should retry with backoff.

Headers

Content-Type

Set to the rendered image’s MIME type. When the URL specifies a format extension (.jpg, .png, .gif), the image is converted to that format; otherwise the source MIME type is preserved. GIF, AVIF, WebP, and SVG content are streamed as-is without processing.

Content-Length

Size of the rendered image, in bytes.

Cache-Control

Set only when the URL includes a fingerprint that matches the current image hash. The value is taken from media.public.cacheControl for content publicly readable on the master branch, and from media.private.cacheControl otherwise. Requests without a fingerprint, or with a stale one, receive no Cache-Control header and are therefore treated as non-cacheable by intermediaries.

Content-Security-Policy

Set when configured via the media.contentSecurityPolicy portal config option. SVG responses use the separate media.contentSecurityPolicy.svg setting, which lets you tighten policy specifically for the inline-script-capable image format.

Content-Encoding

Set to gzip only for .svgz source images — this is a property of the file format (SVGZ is gzipped SVG) and instructs the browser to decompress before rendering.

For all other formats, no Content-Encoding is set by default. The platform-wide Jetty gzip filter is disabled out-of-the-box (gzip.enabled = false), so images are served uncompressed unless an operator opts in. This default keeps the API edge-cache and CDN friendly — services like Fastly can perform their own conditional compression without conflicting with an upstream Content-Encoding.

Configuration

The Image API is driven by two configuration files in your XP installation.

CMS configuration

Controls media-serving behaviour: media.public.cacheControl, media.private.cacheControl, media.contentSecurityPolicy, media.contentSecurityPolicy.svg, and the per-virtual-host endpoint.media.scope attribute.

System configuration

Controls platform-wide HTTP behaviour, including the Jetty gzip filter (gzip.enabled, gzip.minSize) referenced in the headers section above.


Contents

Contents