npm package: @ibm-wch-sdk/ng-rendition
Description: Support package for @ibm-wch-sdk/ng to work with images and renditions.
Author: Dr. Carsten Leue
Latest version: 6.0.524

# ibm-wch-sdk-ng-rendition

Module that allows to attach rendition support to a [WCH](https://www.npmjs.com/package/ibm-wch-sdk-ng) based [Angular](https://angular.io/) application.

## Usage

Install the module via

```bash
npm install --save ibm-wch-sdk-ng-rendition
```

Add the module to your root application

```typescript
@NgModule({
  ...
  imports: [
    ...
    WchNgRenditionModule.forRoot()
  ],
  ...
})
export class AppModule { }
```

The module exposes the `WchRenditionService` and the `wchRendition` directive.

## Prereqs

* [ibm-wch-sdk-ng](https://www.npmjs.com/package/ibm-wch-sdk-ng)
* Angular 4.0 or higher (including Angular 5)

## Usecase

WCH offers the concept of [Renditions](https://developer.ibm.com/customer-engagement/videos/image-renditions-watson-content-hub/) when working with managed image assets. Each managed image asset has the original image plus zero or more variations of that image. Each variation is a (scaled) detail of the original image, called a `Rendition`. The purpose is to allow the business user to define the look of the image in different aspect ratios and sizes.

From a developer's perspective it is challenging to select the correct rendition in a given rendering scenario, because:

* there is guarantee that a concrete instance of an image has a defined rendition, even if the rendition is defined on the content type. The developer has to dynamically find the correct rendition at runtime and cannot rely on an out of band type contract.
* for fluid width image layouts, finding the correct rendition is not evident, since it is improbable that the actual image dimension on the device exactly matches any of the renditions. Finding the `best match` is a multi-dimensional optimization problem. In particular developers want to avoid to use renditions that produce larger images than required, to save bandwidth. On the other hand, using too small renditions causes pixelated, non-optimal image rendering.
* letting the browser select via [srcset](https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-element) is not optimal either, because all possible resolutions must be enumerated. With WCH however we can dynamically compute scaled images at any resolution.

## Solution

The `ibm-wch-sdk-ng-rendition` library solves this issue by calculating the optimum image transform dynamically based on measuring the real estate on the device, finding the best matching rendition and the scaling the rendition to give the best possible result. The selection algorithm is based upon the following assumptions:

* the primary purpose of defining a rendition is to define how the image looks for a particular aspect ratio.
* the secondary purpose is to define the detail of an image for a given aspect ratio in varying sizes.

Based on these assumptions the library computes the image as follows. It takes the target dimensions of the real estate of the image on the device as an input (which can either be computed by measuring the HTML elements or be provided by the application).

* it first locates the available image renditions that match the target aspect ratio the closest.
* from the resulting list it finds the rendition that is larger and matches the target dimensions the closest. If no larger one exists it selects the closest smaller one.
* from the resulting rendition it cuts out an area to match the target aspect ratio, so the image will not be distorted.
* if the resulting area is larger than the target area, it scales it down to match the target area exactly. Otherwise it uses the smaller area and lets the browser scale it up.

The result of this process is a new URL that targets the Akamai rendition service with the computed scaling and cropping. This guarantees that:

* we never load an image that is larger than the target area
* the image will not be distorted
* the selected detail area will match one that a business user has defined as a rendition as closely as possible

## WchRenditionService

The rendition service exposes an API to compute rendition URLs. This service is the most generic way to work with renditions, it burdens the task to measure the target area to the caller

* `getRenditionUrl(w, h, img): string`: computes the rendition URL for the given image (from the rendering context) such that it can be embedded into a target area of given width and height

## WchRenditionDirective

The directive can be attached to an image element within a WCH layout.

### Usage

```html
<img [wchRendition]="myImage" [relHeight]="0.3">
```

The rendition supports the following parameters:

* `[wchRendition]`: points to the image element from the [RenderingContext](https://www.npmjs.com/package/ibm-wch-sdk-ng#_75b5bd277b568a7b2b1e712449158223312b4e299ce5857e62b07ed9b1685c24). Required.
* `[relWidth]`, `[relHeight]`: floating point numbers between 0 and 1. The numbers specify the size of the image relative to the other dimension. You would e.g. typically specify only one of the directives, e.g. `relHeight`. This would set the height of the image relative to the available width (and vice versa). These properties therefore effectively set the aspect ratio.
* `[imgWidth]`, `[imgHeight]`: numbers that specify the size of the real estate covered by the rendered image in pixels. If any of these numbers are missing, the real estate will be measured. Uses these numbers if you can measure the size more reliably than the automatic measurement.
* `(onImage)`: event sent by the directive to communicate the actual dimensions and the URL of the rendered image.