Datafree Max Image Optimisation
Datafree Max optimises bandwidth by reducing the size of image files. The Datafree Optimiser will automatically reduce the physical dimensions of the image and reduce the quality of the image before downloading to the client for display. Optionally, the image can also be cropped.
While the actual optimisation is performed by the Datafree Image Optimiser on the Datafree server, the transformation requirements are determined by the client App which has knowledge of the actual display characteristics of the device. The client App will then request the appropriate sized image from the server which will apply the transformation and return the optimised image for display.
Images are downloaded in WebP format by default as this is the most efficient way to encode most images. It is possible for the Application developer to override the default format and that is covered in the parameters section of this document.
Managing different screen sizes
Android manages different screen sizes through the use of Density Independent Pixels which provide a means of defining screen layout elements so that they display correctly on different sized devices with different resolution screens.
This is what Android says about DPI:
“A virtual pixel unit that you should use when defining UI layout, to express layout dimensions or position in a density-independent way.
The density-independent pixel is equivalent to one physical pixel on a 160 dpi screen, which is the baseline density assumed by the system for a "medium" density screen. At runtime, the system transparently handles any scaling of the dp units, as necessary, based on the actual density of the screen in use. The conversion of dp units to screen pixels is simple: px = dp * (dpi / 160). For example, on a 240 dpi screen, 1 dp equals 1.5 physical pixels. You should always use dp units when defining your application's UI, to ensure proper display of your UI on screens with different densities.”
Datafree Max uses the Android Medium screen size as a reference density, this screen size is 160 dpi so all image width and height parameters should relate to that screen size.
Parameters and Defaults
The Application developer can specify transformation parameters in a number of places and inherit down to the actual request. Each ‘lower level’ value overrides a previous, higher level value (similar to CSS).
The hierarchy is:
- app manifest - this is coded into the Datafree App when it is generated. The manifest provides defaults for quality and crop for the Application.
- <webview> and <img> elements - these may contain the attribute ‘binuimgopt’ which defines the image transformations to use within that element. Only a subset of image transformations are available as attributes, they are listed in the table below.
<webview binuimgopt=’c_crop’ >
<img binuimgopt=’c_crop’ >
- image src URL - this may be appended with image transformation arguments to be applied to that image. The available image transformations are listed in the table below.
Transformation Parameters, Datafree defaults and availability.
|crop & scale
|gravity (defines the part of image to be used if cropped)
|display width and height dimensions
Pre-coded Image URLs
An image URL can be pre-encoded to ignore the values specified in the Application and explicitly define the action to be applied to the image, which can be an explicit transformation or a request to completely bypass image optimisation.
The pre-coded URL can take two forms
- Override Datafree optimisation:
- Ignore Datafree optimisation:
Datafree Max Display Dimensions
In addition to the parameters supported by Cloudinary there are special Datafree Max parameters, the display width (dw) and the display height (dh). These allow the publisher to define the size they want the image to be displayed in terms of the device independent pixels of the screen but the images are still downloaded with the pixel density defined by the EPD in order to optimise data usage. For example, if the display_width is specified at 50% of display width on a phone with a layout width =360, the image will be fetched with a width= 180 pixels regardless of the physical size of the screen.
There are 3 ways to specify the size:
dw_230 (integer) scale to 230 pixels. This is identical to fetching an image with w_230. It is included for consistency.
dw_0.3 (fraction) scale to this fraction of the display area size (e.g. 30%)
dw_23.0 (decimal) scale to that percent size of the display area size (e.g. 23%)
For example, On a screen 1080 pixels wide with a DPI=3 the baseline width=360. An image with dw_240 (or w_240) will be fetched with width=240 (Cloudinary w_240) but will be expanded to 3x240=720 real pixels when displayed.
Note: Setting a width of dw_0 has special meaning - see ‘Displaying Images AsIs’
The Cloudinary dimensions define the size of the final image to be downloaded. This can be an exact pixel number or decimal number which defines a scale amount relative to the original image size.
The width parameter (w_) can have 3 meanings:
w_23 (integer) scale to this many pixels
w_0.3 (fraction) scale to this fraction of orig size (e.g. 30%)
w_23.5 (decimal) scale to that percent size of orig (e.g. 23.5%)
If a publisher calculates a width but doesn’t rounding down it can calculate a decimal value and this will be a scale value rather than a pixel count.. e.g. if they calculate they want an image 180.5 pixels wide but will get an image 1.8x (180%) the original size. They will actually be inflating images in Cloudinary before the download.
The pixels size specified will be the download size but is not the display size. Datafree will map this image to the baseline layout dimension. The image will be displayed with width*DPI physical pixels. The ImageDPR specified is ignored.
If the image is displayed in a Webview, Datafree will inflate the image based on the DPI before returning it to the Webview. The actual display size will typically depend on display data in the HTML (see below for more details).
When a dimension is being calculated we often result in lots of small variations of size varied by just one or 2 pixels. This results in a lot of extra transforms and extra caching in Varnish. To avoid this we should always round down images to the nearest 5 pixels. This should not have a major visual impact when displayed.
Working with c_limit
If the original image is smaller than the download size being requested it will, by default, be scaled up to the requested size by Cloudinary. This may then be scaled up by the client to the necessary display size in order to fill the display area.
To stop Cloudinary scaling up the image before it is sent specify the c_limit instruction. Warning: if the image is limited in this way, the client will only scale up to allow for the DPI ratio, it will not scale up the image to fill the available space.
Display Image ‘As Is’
To display an image exactly the size it is loaded specify the display width (dw_) parameter to 0 i.e. dw_0
The image will be displayed exactly the real pixel size of the image downloaded. I.e it is not scaled up to allow for DPI or EPD. It will occupy a much larger area of the display on a phone with DPI=1 than on one has DPI=3.
If the publisher does not know the size of the image but want it to be scaled for pixel density (DPI) then they can specify an instruction of c_scale,w_screenWidth,c_limit. The image will be fetched ‘as is’ and will not be scaled up, but it’s fetched pixel size will be applied to the baseline layout so it will be scaled accordingly for DPI before display.
Note: in all cases the image will only be scaled to a maximum width of the display area.
Using Images in Datafree Max
Images in Markdown
If an image is placed in Markdown the default behaviour will be for Datafree to scale the image to be the full width of the available space (the screen width in raw Markdown or the width of the element in a Layout). If the publisher wants to display the image smaller than this it can be done in 2 ways:
- Specify the image size with image sizing instructions. Eg. To display an image that is 25% of the screen on a phone with screen width 360:
# Stunner speaks out on the lack of jobs in the country
The problem with this is that the image is not optimised for the screen DPI. For large format screens this can be very wasteful.
- Specify the image as a percentage to the Display Width eg:
# Stunner speaks out on the lack of jobs in the country
In this scenario the Datafree client will convert the ‘dw_’ (screen_width) instruction into a pixel size to fetch the image from Cloudinary. Once the image has been fetched it will scale it appropriately for the phone’s DPI.
For example, for a screen of width 1080 with DPI=3 For instruction:
- Request from Cloudinary is width= 1080*0.25/3= 90 pixels:
- Once the image is returned to the client the image is inflated back up to width=90*3=270 pixels before it is displayed.
Images in a Webview
Default parameters can be set on the webview. This is particularly important with Webview as the publisher may not be able to manipulate the image URLs within the HTML.
<webview binuImgOpt=’c_crop’ >
The Max platform does not know the HTML formatting that will control the display size of the image as that is in the HTML which it does not see.
For example, with:
<img src="smiley.gif" alt="Smiley face" height="42" width="42">
We do not see the height/width settings. The publisher will need to place these values on the URL.
alt="Smiley face" height="42" width="42">
If the publisher does not provide those values in the URL we will default to limiting the size of the image to the max width of the screen with parameters:
We allow for pixel density. So screen width for fetching the image is:
maxWidth = screen_width / screen dpr * ImageDpr(manifest parameter)
‘dw_’ sizes are expressed in the layout scale rather than the physical pixel size. Thus, the image fetched will need to be inflated to the physical scale when the DPI != 1.
Displaying Ads within a Webview
When the webview is being used to display ads it may be important that the images are not modified or pulled through Cloudinary. In which case the webview tag should explicitly disable Datafree image optimisation with:
<webview binuImgOpt=’false’ >
Images in a List / Layout
When an image appears in a Layout the client calculates the size of the space where the image will appear. For example, in a column that is 20% of the screen width. The client can use this to request an image of the appropriate screen width and by default. Similarly, if the list contains items of fixed height this can be used to size the image fetched from Cloudinary.
For example, if the screen is 360 pixels wide with a DPI=1 and the image column is 25% of the screen and fixed height of 100 pixels. The client will request an image with:
If the image is tall and thin the full image will appear as a narrow column
If the image is short and wide it will appear as a bar.
If the List items do not have a fixed height the image will appear in full, scaled to the width of the column. The default instruction to Cloudinary will be:
A short image can result in a small list item, a tall image in a large list item.
To ensure an image always fills the allocated space the publisher must specify a height and width and specify the c_fill cropping instruction. Eg: /w_90,h_90,c_fill/ . The c_limit instruction should not be used so images are always scaled up.
Request Size can be ‘Worst Case Scenario’
To optimize response times Max requests an image before it has determined the exact layout of a page. In doing this it calculates the largest possible size it may need even though there may be scenarios where it could be smaller. For example, if the layout defines a column that has a width of 25% this is always assumed to be 25% of the screen (although it may actually be less than this in some circumstances).