Guides

Overview

On-demand Image image transformations using dynamic URL parameters

📘

Make sure to use https://cdn.filespin.io as host so we can deliver on-demand images efficiently for users around the world. If you have custom FileSpin Enterprise CDN, use that CDN host.

On-demand Image (ODI)

On-demand Image (ODI) provides efficient and high-performance delivery of various image sizes to Web and mobile devices. These are images that are optimised for bandwidth and delivery speed. Ideal use cases are:-

  • to display thumbnails and previews
  • display downsized images when original is a very large image - either in pixel size or file size
  • use the global CDN to deliver these resized images on-demand

To request an ODI, use the Asset ID and request a image transformation like below:-

<<CDN_HOST>>/api/v1/assets/{ASSET_ID}/conversions?resize=200,200

Where resize=200,200 requests a resized image of width 200px and height 200px.

📘

FileSpin On-demand images will always be of 72 PPI and preserve aspect ratio. You can specify a maximum width of 2048 and maximum height of 1536. If larger size is specified in options it will default to 2048x1536

AVIF, WebP Support

By default, the returned images will be avif or webp format for supported browsers. AVIF takes precedence over WebP when both are supported by the browser (as indicated by Accept HTTP request header). When Accept header is not specified or does not specify support for avif or webp, jpg is used fallback format with the exception of PNG images. If original image is a PNG, fallback on-demand image will be avif, webp or png in order to support transparency.

📘

Why AVIF

AVIF has better compression than WebP, JPEG, PNG and GIF and is designed to supersede them. AVIF is now supported by all modern browsers. For more information, please see AVIF at Mozilla Developer Docs and AVIF info at caniuse.com

The default on-demand image content type can be overridden using the format option.

Here is a sample on-demand image request URL used in a img tag:-

<img
  src="<<CDN_HOST>>/api/v1/assets/0c3c6d026858460abc4de1dcb4de15ac/conversions?resize=200,200"
/>

The following sections describe all the image transformations supported.


ODI Limitations

  • On-demand image (ODI) is available for assets after they are processed. Availability of ODI for an asset is indicated with the ON_DEMAND_IMAGE key in addons_info. See Asset Data Format for more info.
  • For large images and cloud files, FileSpin would return a low-resolution thumbnail image if ODI is requested immediately after upload. A short expiration time will be returned in HTTP response header in this case. The ODI URL will be updated with the normal ODI image after the file is processed, usually under 2 seconds.
  • Note that ODI image has a maximum resolution of 2048x1536 and 72 PPI. If the original image has a larger resolution and higher PPI, ODI will be of lower quality than the original. Hence, ODI should not be used for purposes where original image quality is required.

resize

Request a resized image that fits in a rectangle of given width and height without changing the aspect ratio.

TransformationExamplesDescription
resize=width,heightresize=100,100request a resized image that fits in a rectangle of given width, height
resize=width,height,fill:colorresize=100,150,fill:red resize=100,100,fill:blueresize and fill any gaps with given color

The transformation parameters are described below:-

ParameterDescription
widthwidth of the transformation requested. Specify 0 (zero) for original source image width or the maximum allowed (2048)
heightheight of the transformation requested. Specify 0(zero) for original source image height or the maximum allowed (1536)
fill:color(optional) fill color to fit to the specified size when preserving aspect ratio. color can be auto, transparent or HTML color name such as red or hexadecimal color code such as FF0000

crop

Get a cropped region from the original image

TransformationExamplesDescription
crop=left,top,width,heightcrop=150,170,200,50request a cropped region from the original image
crop=width,height,aligncrop=150,100,face crop=150,100,left crop=150,100,right crop=150,100,top crop=150,100,bottom crop=150,100,centerrequest a cropped region with output centered around a area or face/feature
crop=width,heightcrop=150,100request a cropped region with output centered around a face/feature as default

The transformation parameters are described below:-

ParameterDescription
leftleft pixel co-ordinate for the crop
toptop pixel co-ordinate for the crop
widthwidth of the cropped image
heightheight of the cropped image
alignalignment for automatic crop for given width and height. Can be left, right, top, bottom, center or face. face aligns the center of image to most prominent face or feature in the image.

watermark

Watermarked image transformations can be done in two ways:-

  1. Providing dynamic watermark options such as watermark image, placement, etc as URL parameters
  2. Using the pre-defined watermark options already setup in the user's account settings

Watermark option can be combined with all other transformation options such as resize, crop, etc.

Using dynamic watermark options

watermark={watermark_image},{x},{y}{opacity},{width_scale},{height_scale}

Generate a watermarked image transformation by providing all the watermark options as URL parameters. This method allows you to apply different watermarks for the same image depending on the use case.

ParameterDescription
watermark_imageWatermark image URL such as <http://www.example.com/logo.png>
xHorizontal watermark position starting at left: integer like 0 or 10 - negative value such as -0 will start placement at right, center - places watermark in the center, repeat - repeats the watermark horizontally
yVertical watermark position starting at top : integer like 0 or 10 - negative value such as -0 will start placement at bottom, center - places watermark in the center, repeat - repeats the watermark vertically
opacitywatermark image transparency, 0 is fully opaque, 100 is fully transparent, other integer values in between to alter opacity
width_scale(optional) percentage of the width of the image the watermark should fit-in. For example 20 would scale the watermark to fit within 20% of the image's width. Note: watermark aspect ratio will be preserved
height_scale(optional) percentage of the height of the image the watermark should fit-in

Examples

Uses FileSpin logo as watermark and places it to the bottom right of the image. Watermark image is used with the original size. Note the use of -0,-0 to place the watermark at the bottom right of the image.

**`watermark=<%= config[:API_HOST] %>/static/img/logo.png,-0,-0,0`**

watermark=<<API_HOST>>/static/img/logo.png,-0,-0,0

The complete URL would look like:-
<<CDN_HOST>>/api/v1/assets/0c3c6d026858460abc4de1dcb4de15ac/conversions?resize=1200,1200&watermark=<<API_HOST>>/static/img/logo.png,-0,-0


Use FileSpin logo as watermark and places it to the right top of the image. Watermark takes 40% of the image's width and height and opacity is 0 for fully opaque watermark.

**`watermark=<%= config[:API_HOST] %>/static/img/logo.png,-0,0,0,40,40`**

watermark=<<API_HOST>>/static/img/logo.png,-0,0,0,40,40

The complete URL would look like:-
<<CDN_HOST>>/api/v1/assets/0c3c6d026858460abc4de1dcb4de15ac/conversions?resize=1200,1200&watermark=<<API_HOST>>/static/img/logo.png,-0,0,0,40,40


Use FileSpin logo as watermark and repeats it horizontally at the bottom. Watermark takes 40% of the image's width and height.

**`watermark=<%= config[:API_HOST] %>/static/img/logo.png,repeat,-0,0,40,40`**

watermark=<<API_HOST>>/static/img/logo.png,repeat,-0,0,40,40

The complete URL would look like:-
<<CDN_HOST>>/api/v1/assets/0c3c6d026858460abc4de1dcb4de15ac/conversions?resize=1200,1200&watermark=<<API_HOST>>/static/img/logo.png,repeat,-0,0,40,40

Using User's default watermark

The complete URL would look like:-
<<CDN_HOST>>/api/v1/assets/0c3c6d026858460abc4de1dcb4de15ac/conversions?resize=1200,1200&watermark=<<API_HOST>>/api/v1/user/watermark/{USER_ID},0,0,0

watermark=<<API_HOST>>/api/v1/user/watermark/{USER_ID},0,0,0

Where {USER_ID} should be replaced with the user's ID. Note that https://app.filespin.io/api/v1/user/watermark/{USER_ID} is accessible publicly.

This option applies the watermark setup in the user's account settings.

background color

Fill transparent parts of a PNG image with a specified color. This is useful when you want fill an image that has transparent background with a specific color dynamically to match the web page style (such as in retail product image pages).

📘

This options will be ignored for non-PNG images that do not have transparency. The returned image is JPG by default. This can be changed with format option.

Example

Consider this original PNG image with transparent background. Due to the transparent background of the image, you see the page color as the background color.

Below are some transformations with bgcolor that fills the background transparency with a specified color.

TransformationExamplesDescription
bgcolor=f00000request a image with red background
bgcolor=008080request a image with teal background

The transformation parameters are described below:-

ParameterDescription
bgcolor=colorspecify the hex color code (6 characters - RRGGBB).

quality

Specify the quality of the returned image (a value from 1 to 100). If not specified, default quality of 90 is applied.
Quality determines the returned file size in bytes. Lower quality will yield smaller file size and hence faster page loads.

📘

quality can be combined with all other options except with format=png. quality option is ignored when PNG format is requested.

TransformationDescription
quality=integerrequest a image transformation with a specific quality

The transformation parameters are described below:-

ParameterDescription
qualitya value from 1 to 100. Default is 90

format

Specify the format of the returned image. If not specified, format is implicitly set to avif or webp for supported browsers with JPG as fallback format.

📘

format can be combined with all other options.

TransformationExamplesDescription
format=typeformat=pngrequest a png image
format=type&resize=width,heightformat=png&resize=100,100request resized png image

The transformation parameters are described below:-

ParameterDescription
typewebp, avif, png, jpg or gif

trim

Trim removes the same color pixels from the edges of the image. This is useful when you want to remove the white space around an image.

📘

trim can be combined with all other options.

TransformationExamplesDescription
trim=tolerancetrim=20&resize=100,100 trim=10&resize=100,100request a trimmed image with tolerance

The transformation parameters are described below:-

ParameterDescription
tolerancecan be 0 to 10, where 0 compares edge pixel colors strictly and 10 treats them equal if they are close enough. A tolerance of 10 will trim even if they are small color gradient in surrounding pixels.

rotate

Rotate the image anti-clockwise by an angle.

📘

rotate can be combined with all other options.

TransformationExamplesDescription
rotate=anglerotate=90&resize=100,100request a image rotated 90 degrees anti-clockwise
rotate=angle&resize=width,heightrotate=180&resize=100,100 request a 180 degress rotated resized image

The transformation parameters are described below:-

ParameterDescription
anglecan be 90, 180 or 270

flip

Flip an image left to right (horizontal) or top to bottom (vertical).

📘

flip can be combined with all other options.

TransformationExamplesDescription
flip=typeflip=v&resize=100,100 request a image flipped along vertical axis (left/right flip)
flip=type&resize=width,heightflip=h&resize=100,100 request a image flipped along horizontal axis (top/down) and resized

The transformation parameters are described below:-

ParameterDescription
typev for vertical flip, h for horizontal flip

Effects

Effects are transformations applied after all other conversion options such as width, height, etc are applied.

📘

effects can be combined with all other options. In addition, multiple effects can be combined.

ParameterDescription
effectcan be grayscale, blur, roundcorner

grayscale

Request a grayscale image

TransformationExampleDescription
effects=grayscalerequest a grayscale image
effects=grayscale&resize=200,200request resized grayscale image

blur

Request a blurred image

TransformationExampleDescription
effects=blur&resize=100,100request a blurred image with default blur value of 20
effects=blur:5&resize=200,200request resized blurred image with blur value of 5
ParameterDescription
blur:valuevalue can be from 0 to 150. Default blur is 20

roundcorner

Request a image with round corner

TransformationExampleDescription
effects=roundcorner&resize=100,100request a roundcorner image
effects=roundcorner:50:128:128:128&resize=100,100request roundcorner resized image with a radius of 50 and gray background behind rounded corner
ParameterDescription
roundcorner:radius:r:g:bradius controls the amount of roundedness, defaults to 20. r,g,b are the red, blue and green color values to fill the background behind the rounded corners. The values default to 255,255,255 (white)

Multiple effects

Combine multiple effects

TransformationExampleDescription
effects=grayscale,roundcorner:30&resize=200,200request grayscale roundcorner resized image
effects=blur:5,roundcorner&resize=200,200request roundcorner blurred resized image

Signed URL for image transformations

Signed URL with php

<?php
$api_key = '0c3c6d026858460abc4de1dcb4de15ac'
$string_to_sign = '0c3c6d026858460abc4de1dcb4de15ac?resize=300,300&expiry=1452894790&accessId=IZJTAMBQGAYDAMBQGAYDAMBQGAYDANKT'
$signature = urlencode(base64_encode(hash_hmac('sha1', $string_to_sign, $api_key, true)));
$signed_url = '<<CDN_HOST>>/api/v1/conversions/'.$string_to_sign.'&signature='.$signature
?>

Signed URL with python

import base64, hmac, hashlib, urllib
from six import text_type, b

API_KEY = '0c3c6d026858460abc4de1dcb4de15ac'
string_to_sign = '0c3c6d026858460abc4de1dcb4de15ac?resize=300,300&expiry=1452894790&accessId=IZJTAMBQGAYDAMBQGAYDAMBQGAYDANKT'
signature = urllib.quote_plus(base64.urlsafe_b64encode(hmac.new(b(API_KEY), text_type(string_to_sign).encode('utf-8'), hashlib.sha1).digest()))
signed_url = '%s%s&signature=%s' % ('<<CDN_HOST>>/api/v1/conversions/',string_to_sign,signature)

Signed URL with java

import java.security.SignatureException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

String api_key = "0c3c6d026858460abc4de1dcb4de15ac";
String string_to_sign = "0c3c6d026858460abc4de1dcb4de15ac?resize=300,300&expiry=1452894790&accessId=IZJTAMBQGAYDAMBQGAYDAMBQGAYDANKT";
SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(api_key);
byte[] hmac = mac.doFinal(string_to_sign.getBytes());
String signature = Encoding.EncodeBase64(hmac);
String signed_url = "<<CDN_HOST>>/api/v1/conversions/" + string_to_sign + "&signature=" + signature;

Signed URL with nodejs

const crypto = require("crypto");
const API_KEY = "0c3c6d026858460abc4de1dcb4de15ac";
const string_to_sign =
  "f99255d2bf8142b29561641491e9940c/conversions?resize=500,500&expiry=1452894790&accessId=IZJTAMBQGAYDAMBQGAYDAMBQGAYDANKT";

const hash = crypto
  .createHmac("sha1", API_KEY)
  .update(string_to_sign)
  .digest("base64");
const signature = encodeURIComponent(hash.replaceAll("/", "_"));

const signed_url = `<<CDN_HOST>>/api/v1/assets/${string_to_sign}&signature=${signature}`;
console.log(signed_url);

If Secure On-demand Images option is enabled in your settings, then you must use signed URLs for on-demand images.

📘

URL signing code samples are under language tabs.

Steps to generate signed URL

Besides the File Id and size parameters, you'll need the below:-

ParameterTypeDescription
API KeystringYour API Key. This is available in your Authorization Settings page.
EXPIRYintegerSeconds since Unix Epoch time.
ACCESS_IDstringAccess Id that must be used to sign URLs. You can obtain your account's Access Id from the Authorization Settings page.

Signing a image URL is done by setting an expiry and signing the URL using your FileSpin API_KEY and Access Id. The signing process is as below:-

  1. Take the URL part staring with the ASSET_ID, excluding the signature part, like 0c3c6d026858460abc4de1dcb4de15ac?resize=300,300&expiry=1452894790&accessId=IZJTAMBQGAYDAMBQGAYDAMBQGAYDANKT, where expiry is seconds since Epoch time
  2. Using your API Key, Access Id and the above URL part as the string-to-sign, calculate the HMAC signature
  3. Encode the signature to a base64 string, then URL encode the resulting string and append it to the URL as signature query parameter value

Example signed image URL

<<CDN_HOST>>/api/v1/assets/0c3c6d026858460abc4de1dcb4de15ac/conversions?resize=300,300&expiry=1452894790&accessId=IZJTAMBQGAYDAMBQGAYDAMBQGAYDANKT&signature=vsR0_NFfeLEJPc8MXWMh2xI2Qvg%3D

🚧

Note that the parameter values must be url-encoded otherwise FileSpin may return a authorization error.

Downloadable URL for image transformations

These options allow you to set additional URL parameters that sets Content-Disposition HTTP headers such that when user accesses the URL via a browser, the image transformation downloads to their device as a file with appropriate extension.

📘

Note that these parameters are in addition to other transformation parameters.

The parameters are described below:-

ParameterDescription
deliverySet this to download
dl_prefixSet this to the name of the download file without the extension
formatMandatory parameter for image downloads to set the format of the file. Do not set this if already set via format option

Example downloadable image URL

The URL below will download a 300x300 image transformation called testimage.jpg to user's device.

<<CDN_HOST>>/api/v1/assets/0c3c6d026858460abc4de1dcb4de15ac/conversions?resize=300,300&delivery=download&dl_prefix=testimage&format=jpg