Adaptive Delivery

Adaptive Delivery is an Uploadcare's full-stack image optimization solution. It adapts images to user context: screen size, browser, location, and other parameters. The optimization includes lazy loading, smart compression, WebP, responsive images, and retina display support. Altogether, it speeds up page loading and improves user experience without any coding.

It's a leap forward in a responsive image technology that traditionally uses srcset image attribute and viewport sizes. With Adaptive Delivery, all frontend tasks are automated, no image versions and additional code is required. Image optimization is performed on the fly at the time of user requests and the results get cached on CDN nodes. You can store images with Uploadcare or keep them on your hosting.

How to use

After you integrate Adaptive Delivery JS Library, you can selected images you want to optimize automatically to a user's context on delivery.

Simply replace src image attribute with data-blink-src in an HTML code of your webpage to serve this image via Adaptive Delivery. Uploadcare will automatically relay your original image to the CDN and serve it optimized.

Adaptive delivery on various screens

On top of the Adaptive Delivery functions, you can apply Uploadcare's filters and transformations. For example, Auto Enhance, Smart Crop, watermarks, and more.

Integration

Follow these three simple steps to integrate Adaptive Delivery.

Step 1. Connect the JS Library

Use the following code to connect the Adaptive Delivery JS Library:

<script>
   (function(src, cb) {
    var s = document.createElement('script'); s.setAttribute('src', src);
    s.onload = cb; (document.head || document.body).appendChild(s);
  })('https://ucarecdn.com/libs/blinkloader/3.x/blinkloader.min.js', function() {
    window.Blinkloader.optimize({
      pubkey:'YOUR_PUBLIC_KEY',
      fadeIn:true,
      lazyload:true,
      smartCompression:true,
      responsive:true,
      retina:true,
      webp:true
    });
  })
</script>

Note: Replace YOUR_PUBLIC_KEY with your Public API Key to identify the target project for storing images.

Note: Control lazyload, retina, and other options. true is set by default. Read more in Configuration.

There're two ways to integrate Adaptive Delivery:

  • Standard, for plain HTML websites (no Webpack and other JavaScript bundler). Simply add the code above to the webpage's <head>.
  • SPA, for single-page applications built with React or another framework and that use Webpack or a similar JavaScript bundler. Run the code snippet at your app initialization. Put it into a component or helper function if you like.

The JS Library is lightweight (3kb) and sturdy. It provides a fallback to original images in case something goes wrong.

Step 2. Whitelist image sources (optional)

Skip this step if you host images with Uploadcare.

If you use other image sources, add their domains to the list of allowed domains (e.g., yourdomain.com). It helps protect your account. For example, it prevents from uploading images to your project by third parties, eating up your storage and traffic.

To allow an image origin, go to the SettingsProxy, click Connect, and Add domains you are planning to use. Add multiple domains if you need.

Step 3. Usage

Replace src attributes with data-blink-src within your img HTML elements.

<img data-blink-src='https://storage.example.com/logo.png'/>

<!-- same goes for background images -->
<div data-blink-src='https://storage.example.com/banner.png'>
  There is a banner behind this text.
</div>

If you use Uploadcare to host images, you can also use a file UUID instead of a URL. Like this:

<img data-blink-uuid='6493f2d1-a476-427f-bcd5-94330cc02837'/>

<!-- same goes for background images -->
<div data-blink-uuid='6493f2d1-a476-427f-bcd5-94330cc02837'>
  There is a banner behind this text.
</div>

Once you’re done with the replacements, your images get instantly responsive, optimized, and lazy-loaded (depending on the set of the features seleted on the Step 1 and Step 3).

After Blinkloader is initialized, the library starts tracking node changes in DOM. Blinkloader listens to adding new elements to DOM with [data-blink-uuid] and [data-blink-src] attributes, and applies optimization functions to these elements.

Read on to learn about adding additional filters and image transformations or implement our Advanced Configuration options.

Step 4. Add image filters and effects (Optional)

You can apply any of the supported image filters and transformations via the data-blink-ops attribute:

<div
  data-blink-ops='filter: pamaya; filter-amount: 30; mirror; enhance: 100'
  data-blink-src='https://images.unsplash.com/photo-1501281668745-f7f57925c3b4'
/>

Here’s a before-after example:

Picture of a car before filters and effectsEnhanced and filtered picture of the car

The main Adaptive Delivery advantage for a front end developer is that you don’t need to add srcsets, media queries, image resizing and other operations. When you apply Adaptive Delivery, Uploadcare will handle all that automatically.

Configuration

You can customize your Adaptive Delivery experience through our Advanced Configuration options.

Image fade-in

We recommend using a fade-in effect to add a smooth visual transition once images are ready to load. Fade In is disabled by default since you might be using other transition effects on your end. Here’s how you enable the option:

Blinkloader.optimize({
  pubkey: 'YOUR_PUBLIC_KEY',
  fadeIn: true
})

Lazy loading

Lazy-loading is enabled by default. You can explicitly turn it off or customize the behavior.

There are two configurable parameters: “batch interval” and “batch size.” When your page visitors engage in scrolling, our AD Library starts fetching images in batches. “Batch size” defines the number of images for a single fetch, while “batch interval” sets the interval between loading batches, in milliseconds.

If you have many images laid out in a grid, we recommend setting batchSize to 10. If there are one or two images per screen, batchSize should be kept smaller. For batchInterval, it’s vice-versa. You can tweak the parameters to find an optimal combination for your layout or stick with the defaults.

If you’re implementing a different lazy-loading mechanic, you can switch off the option by setting lazyload to false:

Blinkloader.optimize({
  pubkey: 'YOUR_PUBLIC_KEY',
  lazyload: true, // true by default
  batchInterval: 250, // 250ms by default
  batchSize: 10, // 5 by default
})

Before-render hook

Implementing the before-render hook is an efficient way to add a custom UI logic for each image. The function is applied to every image and gets triggered right before it’s ready to render. You can add or remove CSS classes, configure overlays, etc.

Blinkloader.optimize({
  pubkey: 'YOUR_PUBLIC_KEY',
  beforeRender: function(node) {
    // node is a DOM element of the rendered image
    console.log(node);

    // add special effects or remove preloading overlays
    node.classList.add('cool-transition')
  }
})

Progressive loading

We noticed that users prefer using a fade-in transition rather than progressive loading. Hence, progressive loading is disabled by default. You explicitly enable the behavior by stating progressive: true:

Blinkloader.optimize({
  pubkey: 'YOUR_PUBLIC_KEY',
  progressive: true
})

Fallback

Fallback is enabled by default and supports reliable image loading regardless of any conditions. Initially, we serve optimized images from our CDN, and if something goes wrong (unexpected image source, for instance), we render your original image.

Fallback is also automatically activated when you use fadeIn or beforeRender.

Setting fallback to false disables the behavior:

Blinkloader.optimize({
  pubkey: 'YOUR_PUBLIC_KEY',
  fallback: false // true by default
})

Custom CNAME

cdnBase

Specify your custom CNAME in the cdnBase option. When empty, it's set to https://ucarecdn.com by default.

Blinkloader.optimize({
  pubkey: 'YOUR_PUBLIC_KEY',
  cdnBase: 'https://cdn.mycompany.com'
})

host

Specify your custom Endpoint for Proxy in the host option, which is YOUR_PUBLIC_KEY.ucr.io by default.

When you use host, there's no need to specify pubkey.

Blinkloader.optimize({
  host: 'mydomain.ucr.io'
})

Extra-large images

The output image size limit delivered with CDN is 3000 px in either dimension. JPEG images can be resized up to 5000 px. For that, you need to set the image format explicitly.

Adaptive Delivery will resize an image up to 5000 px automatically, when:

  1. data-blink-src has a file extension jpeg or jpg (case-insensitive). For example, https://yourdomain.com/image.jpg
  2. data-blink-format is auto or jpeg. When you set webp:true (default), auto is set implicitly.

Workaround: to have PNG and WEBP image formats up to 5000 px on delivery, rename files so that they have a jpeg file extension (even though they're not). However, the alpha channel will be lost.

Transformations

You can add additional Image Transformations within Adaptive Delivery to serve both optimized and enhanced images. There are two ways to add Image Transformations:

  • Inline a set of transformations in a single data-blink-ops attribute.
  • Add individual transformations via corresponding data attributes.

Here’s an example of using data-blink-ops with its syntax similar to inline CSS:

<img
  data-blink-ops='filter: nerion; enhance: 15; mirror'
  data-blink-src='https://storage.example.com/logo.png'
/>

If you decide to go with individual data attributes, the above example can be rewritten in the following way:

<img
  data-blink-filter='nerion'
  data-blink-enhance='15'
  data-blink-mirror
  data-blink-src='https://storage.example.com/logo.png'
/>

Note, Adaptive Delivery JS Library adds resize, format and quality automatically. We don’t recommend changing the behavior, since we calculate the transformation parameters based on the user context.

Applying image transformations for adaptive delivery differs from our regular URL directives approach, but it supports almost the same set of image transformations with the same limits.

List of image transformations

Resize and Crop

Preview

preview: :two_dimensions

Reduces an image proportionally for it to fit into the given dimensions in pixels. If dimensions are not specified, we use the default value of 2048x2048 pixels.

Resize

resize: :one_or_two_dimensions

Resizes an image to fit into the specified dimensions. With just a single linear dimension specified, preserves your original aspect ratio and resizes an image along one of its axes.

Change resize behavior

stretch: :mode

Sets the resize behavior when a source image is smaller than the resulting dimensions. The following modes can apply:

  • on — stretches an image up, the default option.
  • off — forbids stretching an image along any dimension that exceeds image size along any of its axes.
  • fill — does not stretch an image, the color-filled frame is rendered around instead, the default fill color is used.
City skyline image
preview: 160x160
resize: 220x
City skyline image not stretched
preview: 160x160
stretch: off
resize: 220x
City skyline image, tretched with a background fill
preview: 160x160
stretch: fill
resize: 220xsetfill: 8d8578

Crop

crop: :two_dimensions
crop-position: :two_coords

Crops an image using specified dimensions and offsets. If no offset values are passed into the operation, the top-left image corner is used by default.

Original image
Original image.
Cropped image centered
crop: 200x130; crop-position: center
Cropped image area
crop: 200x130; crop-position: 200,70

Scale crop

scale-crop: :two_dimensions
scale-crop-position: :type

When :type is not specified.

The transformation scales down an image until one of its dimensions gets equal to some of the specified ones; the rest is cropped. This proves useful when your want to fit as much of your image as possible into a box. Let us compare the two resizing methods:

Resized and distorted image
resize: 1024x1024
Requested size.
Distorted.
Resized image, no distortion
preview: 1024x1024
Adjusted size.
No distortion.
Scaled and cropped image
scale-crop: 1024x1024
Requested size.
No distortion.

Smart crop

When smart :type is specified.

Switching the crop type to one of the smart modes enables the content-aware mechanic. Uploadcare applies AI-based techniques to detect faces and other visually important objects or regions in images and crops the rest.

Image with smart crop
/scale_crop/1024x1024/smart/
Smart cropping.

Content-aware mechanics of Smart Crop are based on the following methods of image analysis:

  • Face Detection, :type is set to smart_faces. Face detection identifies and locates human faces in digital images.
  • Object Detection, :type is set to smart_object. Object detection identifies and locates the most visually important regions in the image.
  • Corner Points Detection, :type is set to smart_points. This method analyses image pixels to find the high contrast corners in the image, useful for abstract, landscape, and art images. The corner points have much less semantic information than other methods and designed to be used as a fallback.

The methods you include separating by underscore are applied sequentially. The algorithm switches to the next method only if no regions were found by the previous one. For example smart_faces_objects_points applies face detection initially as the first step. Only when no faces are found on an image, the object detection will be used. Finally, when no objects are found, the corner points will be detected.

If specified methods were unable to find regions or points of interest, the :offset setting will be used to crop an image. When no :offsets are specified, images get center-cropped.

Cropped image, auto centered on a face
smart_faces_objects
Centering on faces or objects
when no faces found.
Cropped image, auto centered on objects and faces
smart_objects_faces
Centering on objects or faces
when no objects found.
Image centering on hard edges
smart_points
Centering on corner points.

Possible :type values:

smart (alias for smart_faces_objects_points), smart_faces_objects, smart_faces_points, smart_objects_faces_points, smart_objects_faces, smart_objects_points, smart_points, smart_objects, smart_faces.

Set fill color

setfill: :color

Sets the fill color used with crop, stretch or when converting an alpha channel enabled image to JPEG. The operation uses hexadecimal notation to define colors.

Image, cropped to center, resized on a white background
crop: 440x380
crop-position: center
Image, cropped to center, resized with a color filled background
crop: 440x380
crop-position: center
setfill: ece3d2
PNG image with alpha channel converted to JPEG with a background fill
crop: 440x380
crop-position: center
setfill: ece3d2format: jpeg

Compression

Format

format: :format

Converts an image to one of the following formats:

  • jpeg — JPEG is a lossy image format (good compression, good for photos). JPEG doesn’t support an alpha channel, hence you can use the setfill operation that sets a background color. All browsers support JPEG.
  • png — PNG is a lossless format (good compression only for graphics) with alpha channel support. Supported by all browsers.
  • webp — WebP is a modern image format that supports alpha channel and lossy compression. The format is good for all kinds of images but supported by a limited number of browsers.
  • auto — the image format used for content delivery is set according to the presence of an alpha channel in your input and capabilities of a client.

Technically, the default behavior of auto is about always trying to deliver WebP images based on checking the Accept header.

PNG image with transparency
png 135Kb
Transparent
JPEG image, opaque
jpeg 8.8Kb
Opaque
WEBP image with transparency, 10 times smaller file size than JPG
webp 11.5Kb
Transparent, size is equal
to the opaque one.

Quality

quality: :value

Sets the level of image quality that affects file sizes and hence loading speeds and volumes of generated traffic. quality works with JPEG and WebP images.

The following options can apply:

  • normal — the default setting, suits most cases.
  • better — can be used to render relatively small and detailed previews. ≈125% file size compared to normal.
  • best — useful for hi-res images, when you want to get perfect quality without paying much attention to file sizes. ≈170% file size.
  • lighter — useful when applied to relatively large images to save traffic without significant losses in quality. ≈80% file size.
  • lightest — highest compression ratio, useful for retina displays. ≈50% file size.
  • smart — automatically adjusts image compression and format settings to preserve visual quality while minimizing the file size. The mode is content-aware. Image formats will not be adjusted if you define format explicitly.
Best image quality
best 32Kb
Lighter image file size
lighter 18.6Kb
The lightest image file size
lightest 12.3Kb
Smart resize produced best visual quality and minimum file size
smart 13.8Kb, WebP

Progressive JPEG

progressive: yes
progressive: no

Returns a progressive image. The operation does not affect non-JPEG images, and won’t force the output image format to JPEG.

Colors

Color adjustments

Adjust image color properties by controlling brightness, exposure, gamma, contrast, saturation, vibrance, and warmth.

brightness: :value
exposure: :value
gamma: :value
contrast: :value
saturation: :value
vibrance: :value
warmth: :value

The :value parameter controls the strength of any applied adjustment. Ranges of the :value parameter differ across image transformations. Setting the :value to “zero point” leaves images unchanged.

Operation:value rangeZero point
brightnessfrom -100 to 1000
exposurefrom -500 to 5000
gammafrom 0 to 1000100
contrastfrom -100 to 5000
saturationfrom -100 to 5000
vibrancefrom -100 to 5000
warmthfrom -100 to 1000

The first three adjustments: brightness, exposure, and gamma produce similar results with the following differences:

  • brightness adds :value to each color channel; out-of-range values are cut.
  • exposure and gamma compress color values distribution thus preserving the details.
Image with reduced brightness
brightness: -20
Original image
Original image.
Image with increased brightness
brightness: 20
Image with reduced exposure
exposure: -100
Original image
Original image.
Image with increased exposure
exposure: 80
Image with reduced gamma
gamma: 150
Original image
Original image.
Image with increased gamma
gamma: 70

The next three operations adjust color diversity and dynamic range in images:

  • contrast affects both colors and dynamic range; on increase, images lose both bright and dark details.
  • saturation uniformly bumps up color intensity leaving the dynamic range unchanged.
  • vibrance cleverly increases the intensity of muted colors and leaves the well-saturated ones alone.
Image with reduced contrast
contrast: -25
Original image
Original image.
Image with increased contrast
contrast: 25
Image with reduced saturation
saturation: -25
Original image
Original image.
Image with increased saturation
saturation: 25
Image with reduced vibrance
vibrance: -50
Original image
Original image.
Image with increased vibrance
vibrance: 50

In turn, warmth adjusts color temperature in images.

Image with reduced warmth
warmth: -50
Original image
Original image.
Image with increased warmth
warmth: 50

You can combine any adjustments, and piping the operations won’t get you any performance or precision losses: all adjustments are applied in one pass.

Original image
Original image.
Image with combined adjustments, reduce saturation, increase contrast and warmth
Old photo effect.
saturation: -80
contrast: 80
warmth: 50
Image with combined adjustments, increase exposure, saturation, and warmth
Fresh view.
exposure: 50
saturation: 50
warmth: -30

Automatic image enhancement

enhance: :strength

Provides automatic image enhancement by combining the following transformations: auto levels, auto contrast, and saturation sharpening. The :strength values should be set in the range from 0 to 100. The default value is 50.

Original image
Original image. 10.3Kb
Enhanced image
enhance: 50 13.5Kb
Max enhanced image
enhance: 100 17Kb

Grayscale

You can desaturates images with the grayscale transformation. It has no additional parameters and simply produces a grayscale image output when applied.

grayscale

Original image
Original image.
Black and white image
grayscale

Inverting

Invert images rendering a “negative” of your input,

invert

An example of inverting an image follows,

Original image
Original image.
Image with inverted colors
invert

Filter

You can apply photo filters to your images while keeping them optimized and respnsove with Adaptive Delivery.

filter: :name
filter-amount: :amount

The transformation applies one of predefined photo filters by its :name. Photo filters help streamline your content production through serving consistent visuals across your site pages or content pieces.

:name should be set to one of the following: adaris, briaril, calarel, carris, cynarel, cyren, elmet, elonni, enzana, erydark, fenralan, ferand, galen, gavin, gethriel, iorill, iothari, iselva, jadis, lavra, misiara, namala, nerion, nethari, pamaya, sarnar, sedis, sewen, sorahel, sorlen, tarian, thellassan, varriel, varven, vevera, virkas, yedis, yllara, zatvel, zevcen.

:amount can be set in the range from -100 to 200 and defaults to 100.

The :amount of:

  • 0 stands for no changes in the image, the output is equal to the original.
  • Values in the range from 0 to 100 gradually increase filter strength; 100 makes filters work as designed.
  • Values over 100 emphasizes filter effect: the strength of applied changes.
  • Any negative number would mean subtracting the difference between the filtered and original images from the original. That will produce a “negative filter” effect.
Filtered image (cooler colors)
filter: vevera;
filter-amount: -100
Original image (birds)
Original image.
Filtered image (warmer)
filter: vevera;
filter-amount: 100
Super filtered image
filter: vevera;
filter-amount: 200

All filters provide predictable outputs with the :value ranging from 0 to 100. For some filter presets, setting the :amount value outside those bounds may produce weird results. For example, all filters producing grayscale outputs will result in a negative image when set to the :amount greater than 100. Set to negative values, those will saturate images.

Here’s how all of our filters look like:

Image with applied filter
filter: adaris
Image with applied filter
filter: briaril
Image with applied filter
filter: calarel
Image with applied filter
filter: carris
Image with applied filter
filter: cynarel
Image with applied filter
filter: cyren
Image with applied filter
filter: elmet
Image with applied filter
filter: elonni
Image with applied filter
filter: enzana
Image with applied filter
filter: erydark
Image with applied filter
filter: fenralan
Image with applied filter
filter: ferand
Image with applied filter
filter: galen
Image with applied filter
filter: gavin
Image with applied filter
filter: gethriel
Image with applied filter
filter: iorill
Image with applied filter
filter: iothari
Image with applied filter
filter: iselva
Image with applied filter
filter: jadis
Image with applied filter
filter: lavra
Image with applied filter
filter: misiara
Image with applied filter
filter: namala
Image with applied filter
filter: nerion
Image with applied filter
filter: nethari
Image with applied filter
filter: pamaya
Image with applied filter
filter: sarnar
Image with applied filter
filter: sedis
Image with applied filter
filter: sewen
Image with applied filter
filter: sorahel
Image with applied filter
filter: sorlen
Image with applied filter
filter: tarian
Image with applied filter
filter: thellassan
Image with applied filter
filter: varriel
Image with applied filter
filter: varven
Image with applied filter
filter: vevera
Image with applied filter
filter: virkas
Image with applied filter
filter: yedis
Image with applied filter
filter: yllara
Image with applied filter
filter: zatvel
Image with applied filter
filter: zevcen

Overlay

The overlay transformation allows to layer images one over another.

overlay-uuid: :uuid
overlay-dimensions: :relative_dimensions
overlay-coordinates: :relative_coordinates
overlay-opacity: :opacity

One of the most common use cases here are watermarks: semi-transparent images layered over opaque ones to complicate their unauthorized usage, etc.

  • :uuid — UUID of an image to be layered over input. To be recognized by :uuid, that image should be related to any project of your account.
  • :relative_dimensions — linear dimensions of the overlay image. The aspect ratio of an overlay is preserved. What you set is a maximum linear size along one of the axes: -/overlay/:uuid/50%x50%/ means any linear dimension of the overlay can not exceed 50% in size. Default size setting is 100%.
  • :relative_coordinates — position of the overlay over your input. By default, an overlay is positioned in the top-left corner of an input. Coordinates represent an offset along each of the axes in either pixel or percent format. In general, the coordinate system is similar to the CSS background-position.
  • :opacity — controls the opacity of the overlay in percent format. Your overlay may either be initially semi-transparent or made to be so by tuning :opacity.

Since % is an escape char in URLs, it can’t be used as-is and should be replaced with either %25 escape sequence or the p char, which is a more readable and concise option.

Every overlay parameter is optional and can be omitted. However, the order of the parameters should be preserved.

Image with a positioned watermark
overlay-uuid: b18b5179-b9f6-4fdc-9920-5539f938fc44;
overlay-dimensions: 50%25x50%25;
overlay-opacity: 20%25

Specifying size and opacity, positioning is omitted.
Image with a logo overlay
overlay-uuid: b18b5179-b9f6-4fdc-9920-5539f938fc44;
overlay-dimensions: 50%25x50%25;
overlay-coordinates: center

Specifying size and position, opacity is omitted.

Blur & Sharpen

Blur

blur: :strength

Applies image blur guided by the :strength factor. Uploadcare implements Gaussian Blur with :strength acting as effect intensity in the range from 0 to 5000. The default value is 10. The transformation provides uniform performance in the full range of intensities.

Original image
Original image. 14Kb
Blurred image
blur: 10 7.6Kb
Max blurred image
blur: 100 2.4Kb

Sharpen

sharp: :strength

Applies image sharpening, which is specifically useful for downscaled images. While Adaptive Delivery provides automatic image resizing, you can further tune your visuals with sharpening. :strength values can be in the range from 0 to 20; the default is 5.

Original image (downscaled)
Downscaled image. 16.1Kb
Image with sharp edges
sharp: 10 21.4Kb
Image with ultra sharp
sharp: 20 25Kb

Rotate and flip

Manual Right-Angle Rotation

rotate: :angle

Right-angle image rotation, counterclockwise. The value of :angle must be a multiple of 90.

Original image
Original image.
Image rotate CCV 90 degrees
rotate: 90
Image rotate 180 degrees
rotate: 180
Image rotate CV 90 degrees
rotate: 270

Flip

flip

The transformation provides image flipping.

Original image
Original image.
Vertical flip image
flip

Mirror

mirror

The transformation allows mirroring images.

Original image
Original image.
Horizontal flip image (mirror)
mirror